blob: 631201f2078c826a9bf31f43c198d9bcf0e05d21 [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
Thomas Wouters477c8d52006-05-27 19:21:47 +000014#ifdef __APPLE__
15 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000016 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000017 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
18 * at the end of this file for more information.
19 */
20# pragma weak lchown
21# pragma weak statvfs
22# pragma weak fstatvfs
23
24#endif /* __APPLE__ */
25
Thomas Wouters68bc4f92006-03-01 01:05:10 +000026#define PY_SSIZE_T_CLEAN
27
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000028#include "Python.h"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000029
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000030#if defined(__VMS)
Victor Stinnerb90db4c2011-04-26 22:48:24 +020031# error "PEP 11: VMS is now unsupported, code will be removed in Python 3.4"
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000032# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033#endif /* defined(__VMS) */
34
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000035#ifdef __cplusplus
36extern "C" {
37#endif
38
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000039PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000040"This module provides access to operating system functionality that is\n\
41standardized by the C Standard and the POSIX standard (a thinly\n\
42disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000043corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000044
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000045
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000046#if defined(PYOS_OS2)
Victor Stinnerb90db4c2011-04-26 22:48:24 +020047#error "PEP 11: OS/2 is now unsupported, code will be removed in Python 3.4"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000048#define INCL_DOS
49#define INCL_DOSERRORS
50#define INCL_DOSPROCESS
51#define INCL_NOPMAPI
52#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000053#if defined(PYCC_GCC)
54#include <ctype.h>
55#include <io.h>
56#include <stdio.h>
57#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000058#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000059#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000060#endif
61
Ross Lagerwall4d076da2011-03-18 06:56:53 +020062#ifdef HAVE_SYS_UIO_H
63#include <sys/uio.h>
64#endif
65
Thomas Wouters0e3f5912006-08-11 14:57:12 +000066#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000067#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000068#endif /* HAVE_SYS_TYPES_H */
69
70#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000071#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000072#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000073
Guido van Rossum36bc6801995-06-14 22:54:23 +000074#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000075#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000076#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000077
Thomas Wouters0e3f5912006-08-11 14:57:12 +000078#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000079#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000080#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000081
Guido van Rossumb6775db1994-08-01 11:34:53 +000082#ifdef HAVE_FCNTL_H
83#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000084#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000085
Guido van Rossuma6535fd2001-10-18 19:44:10 +000086#ifdef HAVE_GRP_H
87#include <grp.h>
88#endif
89
Barry Warsaw5676bd12003-01-07 20:57:09 +000090#ifdef HAVE_SYSEXITS_H
91#include <sysexits.h>
92#endif /* HAVE_SYSEXITS_H */
93
Anthony Baxter8a560de2004-10-13 15:30:56 +000094#ifdef HAVE_SYS_LOADAVG_H
95#include <sys/loadavg.h>
96#endif
97
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000098#ifdef HAVE_LANGINFO_H
99#include <langinfo.h>
100#endif
101
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000102#ifdef HAVE_SYS_SENDFILE_H
103#include <sys/sendfile.h>
104#endif
105
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500106#ifdef HAVE_SCHED_H
107#include <sched.h>
108#endif
109
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500110#if defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
111#undef HAVE_SCHED_SETAFFINITY
112#endif
113
Benjamin Peterson9428d532011-09-14 11:45:52 -0400114#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__)
115#define USE_XATTRS
116#endif
117
118#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400119#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400120#endif
121
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000122#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
123#ifdef HAVE_SYS_SOCKET_H
124#include <sys/socket.h>
125#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000126#endif
127
Victor Stinner8b905bd2011-10-25 13:34:04 +0200128#ifdef HAVE_DLFCN_H
129#include <dlfcn.h>
130#endif
131
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100132#if defined(MS_WINDOWS)
133# define TERMSIZE_USE_CONIO
134#elif defined(HAVE_SYS_IOCTL_H)
135# include <sys/ioctl.h>
136# if defined(HAVE_TERMIOS_H)
137# include <termios.h>
138# endif
139# if defined(TIOCGWINSZ)
140# define TERMSIZE_USE_IOCTL
141# endif
142#endif /* MS_WINDOWS */
143
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000144/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000145/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000146#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000147#include <process.h>
148#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000149#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000150#define HAVE_GETCWD 1
151#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000152#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000153#if defined(__OS2__)
154#define HAVE_EXECV 1
155#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000156#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000157#include <process.h>
158#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000159#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000160#define HAVE_EXECV 1
161#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000162#define HAVE_OPENDIR 1
163#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000164#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000165#define HAVE_WAIT 1
166#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000167#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000168#define HAVE_GETCWD 1
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000169#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000170#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000171#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000172#define HAVE_EXECV 1
173#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000174#define HAVE_SYSTEM 1
175#define HAVE_CWAIT 1
176#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000177#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000178#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000179#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
180/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000181#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000182/* Unix functions that the configure script doesn't check for */
183#define HAVE_EXECV 1
184#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000185#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000186#define HAVE_FORK1 1
187#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000188#define HAVE_GETCWD 1
189#define HAVE_GETEGID 1
190#define HAVE_GETEUID 1
191#define HAVE_GETGID 1
192#define HAVE_GETPPID 1
193#define HAVE_GETUID 1
194#define HAVE_KILL 1
195#define HAVE_OPENDIR 1
196#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000197#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000198#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000199#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000200#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000201#endif /* _MSC_VER */
202#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000203#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000204#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000205
Victor Stinnera2f7c002012-02-08 03:36:25 +0100206
207
208
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000209#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000210
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000211#if defined(__sgi)&&_COMPILER_VERSION>=700
212/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
213 (default) */
214extern char *ctermid_r(char *);
215#endif
216
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000217#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000218#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000219extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000220#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000221#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000222extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000223#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000224extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000225#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000226#endif
227#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000228extern int chdir(char *);
229extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000230#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000231extern int chdir(const char *);
232extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000233#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000234#ifdef __BORLANDC__
235extern int chmod(const char *, int);
236#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000237extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000238#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000239/*#ifdef HAVE_FCHMOD
240extern int fchmod(int, mode_t);
241#endif*/
242/*#ifdef HAVE_LCHMOD
243extern int lchmod(const char *, mode_t);
244#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000245extern int chown(const char *, uid_t, gid_t);
246extern char *getcwd(char *, int);
247extern char *strerror(int);
248extern int link(const char *, const char *);
249extern int rename(const char *, const char *);
250extern int stat(const char *, struct stat *);
251extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000252#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000253extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000254#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000255#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000256extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000257#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000259
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000260#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000261
Guido van Rossumb6775db1994-08-01 11:34:53 +0000262#ifdef HAVE_UTIME_H
263#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000264#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000265
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000266#ifdef HAVE_SYS_UTIME_H
267#include <sys/utime.h>
268#define HAVE_UTIME_H /* pretend we do for the rest of this file */
269#endif /* HAVE_SYS_UTIME_H */
270
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271#ifdef HAVE_SYS_TIMES_H
272#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000273#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000274
275#ifdef HAVE_SYS_PARAM_H
276#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000277#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278
279#ifdef HAVE_SYS_UTSNAME_H
280#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000281#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000282
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000283#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000285#define NAMLEN(dirent) strlen((dirent)->d_name)
286#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000287#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000288#include <direct.h>
289#define NAMLEN(dirent) strlen((dirent)->d_name)
290#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000291#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000292#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000293#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000294#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000295#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000296#endif
297#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000298#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000299#endif
300#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000301#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000302#endif
303#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000304
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000305#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000306#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000307#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000308#endif
309#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000310#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000311#endif
312#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000313#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000314#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000315#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000316#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000317#endif
318#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000319#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000320#endif
321#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000322#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000323#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000324#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000325#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000326#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000327#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000328#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000329#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
330#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000331static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000332#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000333#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000334
Guido van Rossumd48f2521997-12-05 22:19:34 +0000335#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000336#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000337#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000338
Tim Petersbc2e10e2002-03-03 23:17:02 +0000339#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000340#if defined(PATH_MAX) && PATH_MAX > 1024
341#define MAXPATHLEN PATH_MAX
342#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000343#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000344#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000345#endif /* MAXPATHLEN */
346
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000347#ifdef UNION_WAIT
348/* Emulate some macros on systems that have a union instead of macros */
349
350#ifndef WIFEXITED
351#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
352#endif
353
354#ifndef WEXITSTATUS
355#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
356#endif
357
358#ifndef WTERMSIG
359#define WTERMSIG(u_wait) ((u_wait).w_termsig)
360#endif
361
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000362#define WAIT_TYPE union wait
363#define WAIT_STATUS_INT(s) (s.w_status)
364
365#else /* !UNION_WAIT */
366#define WAIT_TYPE int
367#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000368#endif /* UNION_WAIT */
369
Greg Wardb48bc172000-03-01 21:51:56 +0000370/* Don't use the "_r" form if we don't need it (also, won't have a
371 prototype for it, at least on Solaris -- maybe others as well?). */
372#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
373#define USE_CTERMID_R
374#endif
375
Fred Drake699f3522000-06-29 21:12:41 +0000376/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000377#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000378#undef FSTAT
379#undef STRUCT_STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000380#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000381# define STAT win32_stat
382# define FSTAT win32_fstat
383# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000384#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000385# define STAT stat
386# define FSTAT fstat
387# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000388#endif
389
Tim Peters11b23062003-04-23 02:39:17 +0000390#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000391#include <sys/mkdev.h>
392#else
393#if defined(MAJOR_IN_SYSMACROS)
394#include <sys/sysmacros.h>
395#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000396#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
397#include <sys/mkdev.h>
398#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000399#endif
Fred Drake699f3522000-06-29 21:12:41 +0000400
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200401/* A helper used by a number of POSIX-only functions */
402#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +0000403static int
404_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000405{
406#if !defined(HAVE_LARGEFILE_SUPPORT)
407 *((off_t*)addr) = PyLong_AsLong(arg);
408#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +0000409 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000410#endif
411 if (PyErr_Occurred())
412 return 0;
413 return 1;
414}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200415#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000416
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000417#if defined _MSC_VER && _MSC_VER >= 1400
418/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
419 * valid and throw an assertion if it isn't.
420 * Normally, an invalid fd is likely to be a C program error and therefore
421 * an assertion can be useful, but it does contradict the POSIX standard
422 * which for write(2) states:
423 * "Otherwise, -1 shall be returned and errno set to indicate the error."
424 * "[EBADF] The fildes argument is not a valid file descriptor open for
425 * writing."
426 * Furthermore, python allows the user to enter any old integer
427 * as a fd and should merely raise a python exception on error.
428 * The Microsoft CRT doesn't provide an official way to check for the
429 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000430 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000431 * internal structures involved.
432 * The structures below must be updated for each version of visual studio
433 * according to the file internal.h in the CRT source, until MS comes
434 * up with a less hacky way to do this.
435 * (all of this is to avoid globally modifying the CRT behaviour using
436 * _set_invalid_parameter_handler() and _CrtSetReportMode())
437 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000438/* The actual size of the structure is determined at runtime.
439 * Only the first items must be present.
440 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000441typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000442 intptr_t osfhnd;
443 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000444} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000445
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000446extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000447#define IOINFO_L2E 5
448#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
449#define IOINFO_ARRAYS 64
450#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
451#define FOPEN 0x01
452#define _NO_CONSOLE_FILENO (intptr_t)-2
453
454/* This function emulates what the windows CRT does to validate file handles */
455int
456_PyVerify_fd(int fd)
457{
Victor Stinner8c62be82010-05-06 00:08:46 +0000458 const int i1 = fd >> IOINFO_L2E;
459 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000460
Antoine Pitrou22e41552010-08-15 18:07:50 +0000461 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000462
Victor Stinner8c62be82010-05-06 00:08:46 +0000463 /* Determine the actual size of the ioinfo structure,
464 * as used by the CRT loaded in memory
465 */
466 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
467 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
468 }
469 if (sizeof_ioinfo == 0) {
470 /* This should not happen... */
471 goto fail;
472 }
473
474 /* See that it isn't a special CLEAR fileno */
475 if (fd != _NO_CONSOLE_FILENO) {
476 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
477 * we check pointer validity and other info
478 */
479 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
480 /* finally, check that the file is open */
481 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
482 if (info->osfile & FOPEN) {
483 return 1;
484 }
485 }
486 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000487 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000488 errno = EBADF;
489 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000490}
491
492/* the special case of checking dup2. The target fd must be in a sensible range */
493static int
494_PyVerify_fd_dup2(int fd1, int fd2)
495{
Victor Stinner8c62be82010-05-06 00:08:46 +0000496 if (!_PyVerify_fd(fd1))
497 return 0;
498 if (fd2 == _NO_CONSOLE_FILENO)
499 return 0;
500 if ((unsigned)fd2 < _NHANDLE_)
501 return 1;
502 else
503 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000504}
505#else
506/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
507#define _PyVerify_fd_dup2(A, B) (1)
508#endif
509
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000510#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +0000511/* The following structure was copied from
512 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
513 include doesn't seem to be present in the Windows SDK (at least as included
514 with Visual Studio Express). */
515typedef struct _REPARSE_DATA_BUFFER {
516 ULONG ReparseTag;
517 USHORT ReparseDataLength;
518 USHORT Reserved;
519 union {
520 struct {
521 USHORT SubstituteNameOffset;
522 USHORT SubstituteNameLength;
523 USHORT PrintNameOffset;
524 USHORT PrintNameLength;
525 ULONG Flags;
526 WCHAR PathBuffer[1];
527 } SymbolicLinkReparseBuffer;
528
529 struct {
530 USHORT SubstituteNameOffset;
531 USHORT SubstituteNameLength;
532 USHORT PrintNameOffset;
533 USHORT PrintNameLength;
534 WCHAR PathBuffer[1];
535 } MountPointReparseBuffer;
536
537 struct {
538 UCHAR DataBuffer[1];
539 } GenericReparseBuffer;
540 };
541} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
542
543#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
544 GenericReparseBuffer)
545#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
546
547static int
Brian Curtind25aef52011-06-13 15:16:04 -0500548win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +0000549{
550 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
551 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
552 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000553
554 if (0 == DeviceIoControl(
555 reparse_point_handle,
556 FSCTL_GET_REPARSE_POINT,
557 NULL, 0, /* in buffer */
558 target_buffer, sizeof(target_buffer),
559 &n_bytes_returned,
560 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -0500561 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000562
563 if (reparse_tag)
564 *reparse_tag = rdb->ReparseTag;
565
Brian Curtind25aef52011-06-13 15:16:04 -0500566 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000567}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100568
569static int
570win32_warn_bytes_api()
571{
572 return PyErr_WarnEx(PyExc_DeprecationWarning,
573 "The Windows bytes API has been deprecated, "
574 "use Unicode filenames instead",
575 1);
576}
577
578static PyObject*
579win32_decode_filename(PyObject *obj)
580{
581 PyObject *unicode;
582 if (PyUnicode_Check(obj)) {
583 if (PyUnicode_READY(obj))
584 return NULL;
585 Py_INCREF(obj);
586 return obj;
587 }
588 if (!PyUnicode_FSDecoder(obj, &unicode))
589 return NULL;
590 if (win32_warn_bytes_api()) {
591 Py_DECREF(unicode);
592 return NULL;
593 }
594 return unicode;
595}
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000596#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +0000597
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000598/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000599#ifdef WITH_NEXT_FRAMEWORK
600/* On Darwin/MacOSX a shared library or framework has no access to
601** environ directly, we must obtain it with _NSGetEnviron().
602*/
603#include <crt_externs.h>
604static char **environ;
605#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000606extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000607#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000608
Barry Warsaw53699e91996-12-10 23:23:01 +0000609static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000610convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000611{
Victor Stinner8c62be82010-05-06 00:08:46 +0000612 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000613#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000614 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000615#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000616 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000617#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000618#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +0000619 APIRET rc;
620 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
621#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000622
Victor Stinner8c62be82010-05-06 00:08:46 +0000623 d = PyDict_New();
624 if (d == NULL)
625 return NULL;
626#ifdef WITH_NEXT_FRAMEWORK
627 if (environ == NULL)
628 environ = *_NSGetEnviron();
629#endif
630#ifdef MS_WINDOWS
631 /* _wenviron must be initialized in this way if the program is started
632 through main() instead of wmain(). */
633 _wgetenv(L"");
634 if (_wenviron == NULL)
635 return d;
636 /* This part ignores errors */
637 for (e = _wenviron; *e != NULL; e++) {
638 PyObject *k;
639 PyObject *v;
640 wchar_t *p = wcschr(*e, L'=');
641 if (p == NULL)
642 continue;
643 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
644 if (k == NULL) {
645 PyErr_Clear();
646 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000647 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000648 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
649 if (v == NULL) {
650 PyErr_Clear();
651 Py_DECREF(k);
652 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000653 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000654 if (PyDict_GetItem(d, k) == NULL) {
655 if (PyDict_SetItem(d, k, v) != 0)
656 PyErr_Clear();
657 }
658 Py_DECREF(k);
659 Py_DECREF(v);
660 }
661#else
662 if (environ == NULL)
663 return d;
664 /* This part ignores errors */
665 for (e = environ; *e != NULL; e++) {
666 PyObject *k;
667 PyObject *v;
668 char *p = strchr(*e, '=');
669 if (p == NULL)
670 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +0000671 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +0000672 if (k == NULL) {
673 PyErr_Clear();
674 continue;
675 }
Victor Stinner84ae1182010-05-06 22:05:07 +0000676 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +0000677 if (v == NULL) {
678 PyErr_Clear();
679 Py_DECREF(k);
680 continue;
681 }
682 if (PyDict_GetItem(d, k) == NULL) {
683 if (PyDict_SetItem(d, k, v) != 0)
684 PyErr_Clear();
685 }
686 Py_DECREF(k);
687 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000688 }
689#endif
Victor Stinner8c62be82010-05-06 00:08:46 +0000690#if defined(PYOS_OS2)
691 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
692 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
693 PyObject *v = PyBytes_FromString(buffer);
694 PyDict_SetItemString(d, "BEGINLIBPATH", v);
695 Py_DECREF(v);
696 }
697 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
698 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
699 PyObject *v = PyBytes_FromString(buffer);
700 PyDict_SetItemString(d, "ENDLIBPATH", v);
701 Py_DECREF(v);
702 }
703#endif
704 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000705}
706
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000707/* Set a POSIX-specific error from errno, and return NULL */
708
Barry Warsawd58d7641998-07-23 16:14:40 +0000709static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000710posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000711{
Victor Stinner8c62be82010-05-06 00:08:46 +0000712 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000713}
Barry Warsawd58d7641998-07-23 16:14:40 +0000714static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000715posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000716{
Victor Stinner8c62be82010-05-06 00:08:46 +0000717 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000718}
719
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000720
Mark Hammondef8b6542001-05-13 08:04:26 +0000721static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +0000722posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +0000723{
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000724 PyObject *name_str, *rc;
725 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
726 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +0000727 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000728 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
729 name_str);
730 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +0000731 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000732}
733
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000734#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000735static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +0000736win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000737{
Victor Stinner8c62be82010-05-06 00:08:46 +0000738 /* XXX We should pass the function name along in the future.
739 (winreg.c also wants to pass the function name.)
740 This would however require an additional param to the
741 Windows error object, which is non-trivial.
742 */
743 errno = GetLastError();
744 if (filename)
745 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
746 else
747 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000748}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000749
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000750static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +0200751win32_error_unicode(char* function, wchar_t* filename)
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000752{
Victor Stinner8c62be82010-05-06 00:08:46 +0000753 /* XXX - see win32_error for comments on 'function' */
754 errno = GetLastError();
755 if (filename)
756 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
757 else
758 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000759}
760
Victor Stinnereb5657a2011-09-30 01:44:27 +0200761static PyObject *
762win32_error_object(char* function, PyObject* filename)
763{
764 /* XXX - see win32_error for comments on 'function' */
765 errno = GetLastError();
766 if (filename)
767 return PyErr_SetExcFromWindowsErrWithFilenameObject(
768 PyExc_WindowsError,
769 errno,
770 filename);
771 else
772 return PyErr_SetFromWindowsErr(errno);
773}
774
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000775#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000776
Guido van Rossumd48f2521997-12-05 22:19:34 +0000777#if defined(PYOS_OS2)
778/**********************************************************************
779 * Helper Function to Trim and Format OS/2 Messages
780 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000781static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000782os2_formatmsg(char *msgbuf, int msglen, char *reason)
783{
784 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
785
786 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
787 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
788
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000789 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000790 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
791 }
792
793 /* Add Optional Reason Text */
794 if (reason) {
795 strcat(msgbuf, " : ");
796 strcat(msgbuf, reason);
797 }
798}
799
800/**********************************************************************
801 * Decode an OS/2 Operating System Error Code
802 *
803 * A convenience function to lookup an OS/2 error code and return a
804 * text message we can use to raise a Python exception.
805 *
806 * Notes:
807 * The messages for errors returned from the OS/2 kernel reside in
808 * the file OSO001.MSG in the \OS2 directory hierarchy.
809 *
810 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000811static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000812os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
813{
814 APIRET rc;
815 ULONG msglen;
816
817 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
818 Py_BEGIN_ALLOW_THREADS
819 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
820 errorcode, "oso001.msg", &msglen);
821 Py_END_ALLOW_THREADS
822
823 if (rc == NO_ERROR)
824 os2_formatmsg(msgbuf, msglen, reason);
825 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000826 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +0000827 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000828
829 return msgbuf;
830}
831
832/* Set an OS/2-specific error and return NULL. OS/2 kernel
833 errors are not in a global variable e.g. 'errno' nor are
834 they congruent with posix error numbers. */
835
Victor Stinner8c62be82010-05-06 00:08:46 +0000836static PyObject *
837os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000838{
839 char text[1024];
840 PyObject *v;
841
842 os2_strerror(text, sizeof(text), code, "");
843
844 v = Py_BuildValue("(is)", code, text);
845 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000846 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000847 Py_DECREF(v);
848 }
849 return NULL; /* Signal to Python that an Exception is Pending */
850}
851
852#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000853
854/* POSIX generic methods */
855
Barry Warsaw53699e91996-12-10 23:23:01 +0000856static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000857posix_fildes(PyObject *fdobj, int (*func)(int))
858{
Victor Stinner8c62be82010-05-06 00:08:46 +0000859 int fd;
860 int res;
861 fd = PyObject_AsFileDescriptor(fdobj);
862 if (fd < 0)
863 return NULL;
864 if (!_PyVerify_fd(fd))
865 return posix_error();
866 Py_BEGIN_ALLOW_THREADS
867 res = (*func)(fd);
868 Py_END_ALLOW_THREADS
869 if (res < 0)
870 return posix_error();
871 Py_INCREF(Py_None);
872 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000873}
Guido van Rossum21142a01999-01-08 21:05:37 +0000874
875static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000876posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000877{
Victor Stinner8c62be82010-05-06 00:08:46 +0000878 PyObject *opath1 = NULL;
879 char *path1;
880 int res;
881 if (!PyArg_ParseTuple(args, format,
882 PyUnicode_FSConverter, &opath1))
883 return NULL;
884 path1 = PyBytes_AsString(opath1);
885 Py_BEGIN_ALLOW_THREADS
886 res = (*func)(path1);
887 Py_END_ALLOW_THREADS
888 if (res < 0)
889 return posix_error_with_allocated_filename(opath1);
890 Py_DECREF(opath1);
891 Py_INCREF(Py_None);
892 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000893}
894
Barry Warsaw53699e91996-12-10 23:23:01 +0000895static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000896posix_2str(PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +0000897 char *format,
898 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000899{
Victor Stinner8c62be82010-05-06 00:08:46 +0000900 PyObject *opath1 = NULL, *opath2 = NULL;
901 char *path1, *path2;
902 int res;
903 if (!PyArg_ParseTuple(args, format,
904 PyUnicode_FSConverter, &opath1,
905 PyUnicode_FSConverter, &opath2)) {
906 return NULL;
907 }
908 path1 = PyBytes_AsString(opath1);
909 path2 = PyBytes_AsString(opath2);
910 Py_BEGIN_ALLOW_THREADS
911 res = (*func)(path1, path2);
912 Py_END_ALLOW_THREADS
913 Py_DECREF(opath1);
914 Py_DECREF(opath2);
915 if (res != 0)
916 /* XXX how to report both path1 and path2??? */
917 return posix_error();
918 Py_INCREF(Py_None);
919 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000920}
921
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000922#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +0000923static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +0000924win32_1str(PyObject* args, char* func,
925 char* format, BOOL (__stdcall *funcA)(LPCSTR),
926 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000927{
Victor Stinner8c62be82010-05-06 00:08:46 +0000928 PyObject *uni;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100929 const char *ansi;
Victor Stinner8c62be82010-05-06 00:08:46 +0000930 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +0000931
Victor Stinnereb5657a2011-09-30 01:44:27 +0200932 if (PyArg_ParseTuple(args, wformat, &uni))
933 {
934 wchar_t *wstr = PyUnicode_AsUnicode(uni);
935 if (wstr == NULL)
936 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +0000937 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +0200938 result = funcW(wstr);
Victor Stinner8c62be82010-05-06 00:08:46 +0000939 Py_END_ALLOW_THREADS
940 if (!result)
Victor Stinnereb5657a2011-09-30 01:44:27 +0200941 return win32_error_object(func, uni);
Victor Stinner8c62be82010-05-06 00:08:46 +0000942 Py_INCREF(Py_None);
943 return Py_None;
944 }
Victor Stinnereb5657a2011-09-30 01:44:27 +0200945 PyErr_Clear();
946
Victor Stinner8c62be82010-05-06 00:08:46 +0000947 if (!PyArg_ParseTuple(args, format, &ansi))
948 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100949 if (win32_warn_bytes_api())
950 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +0000951 Py_BEGIN_ALLOW_THREADS
952 result = funcA(ansi);
953 Py_END_ALLOW_THREADS
954 if (!result)
955 return win32_error(func, ansi);
956 Py_INCREF(Py_None);
957 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000958
959}
960
961/* This is a reimplementation of the C library's chdir function,
962 but one that produces Win32 errors instead of DOS error codes.
963 chdir is essentially a wrapper around SetCurrentDirectory; however,
964 it also needs to set "magic" environment variables indicating
965 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000966static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000967win32_chdir(LPCSTR path)
968{
Victor Stinner8c62be82010-05-06 00:08:46 +0000969 char new_path[MAX_PATH+1];
970 int result;
971 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000972
Victor Stinner8c62be82010-05-06 00:08:46 +0000973 if(!SetCurrentDirectoryA(path))
974 return FALSE;
975 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
976 if (!result)
977 return FALSE;
978 /* In the ANSI API, there should not be any paths longer
979 than MAX_PATH. */
980 assert(result <= MAX_PATH+1);
981 if (strncmp(new_path, "\\\\", 2) == 0 ||
982 strncmp(new_path, "//", 2) == 0)
983 /* UNC path, nothing to do. */
984 return TRUE;
985 env[1] = new_path[0];
986 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000987}
988
989/* The Unicode version differs from the ANSI version
990 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000991static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000992win32_wchdir(LPCWSTR path)
993{
Victor Stinner8c62be82010-05-06 00:08:46 +0000994 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
995 int result;
996 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000997
Victor Stinner8c62be82010-05-06 00:08:46 +0000998 if(!SetCurrentDirectoryW(path))
999 return FALSE;
1000 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
1001 if (!result)
1002 return FALSE;
1003 if (result > MAX_PATH+1) {
1004 new_path = malloc(result * sizeof(wchar_t));
1005 if (!new_path) {
1006 SetLastError(ERROR_OUTOFMEMORY);
1007 return FALSE;
1008 }
1009 result = GetCurrentDirectoryW(result, new_path);
1010 if (!result) {
1011 free(new_path);
1012 return FALSE;
1013 }
1014 }
1015 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1016 wcsncmp(new_path, L"//", 2) == 0)
1017 /* UNC path, nothing to do. */
1018 return TRUE;
1019 env[1] = new_path[0];
1020 result = SetEnvironmentVariableW(env, new_path);
1021 if (new_path != _new_path)
1022 free(new_path);
1023 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001024}
1025#endif
1026
Martin v. Löwis14694662006-02-03 12:54:16 +00001027#ifdef MS_WINDOWS
1028/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1029 - time stamps are restricted to second resolution
1030 - file modification times suffer from forth-and-back conversions between
1031 UTC and local time
1032 Therefore, we implement our own stat, based on the Win32 API directly.
1033*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001034#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001035
1036struct win32_stat{
1037 int st_dev;
1038 __int64 st_ino;
1039 unsigned short st_mode;
1040 int st_nlink;
1041 int st_uid;
1042 int st_gid;
1043 int st_rdev;
1044 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001045 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001046 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001047 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001048 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001049 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001050 int st_ctime_nsec;
1051};
1052
1053static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1054
1055static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001056FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001057{
Victor Stinner8c62be82010-05-06 00:08:46 +00001058 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1059 /* Cannot simply cast and dereference in_ptr,
1060 since it might not be aligned properly */
1061 __int64 in;
1062 memcpy(&in, in_ptr, sizeof(in));
1063 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001064 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001065}
1066
Thomas Wouters477c8d52006-05-27 19:21:47 +00001067static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001068time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001069{
Victor Stinner8c62be82010-05-06 00:08:46 +00001070 /* XXX endianness */
1071 __int64 out;
1072 out = time_in + secs_between_epochs;
1073 out = out * 10000000 + nsec_in / 100;
1074 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001075}
1076
Martin v. Löwis14694662006-02-03 12:54:16 +00001077/* Below, we *know* that ugo+r is 0444 */
1078#if _S_IREAD != 0400
1079#error Unsupported C library
1080#endif
1081static int
1082attributes_to_mode(DWORD attr)
1083{
Victor Stinner8c62be82010-05-06 00:08:46 +00001084 int m = 0;
1085 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1086 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1087 else
1088 m |= _S_IFREG;
1089 if (attr & FILE_ATTRIBUTE_READONLY)
1090 m |= 0444;
1091 else
1092 m |= 0666;
1093 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001094}
1095
1096static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001097attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001098{
Victor Stinner8c62be82010-05-06 00:08:46 +00001099 memset(result, 0, sizeof(*result));
1100 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1101 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1102 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1103 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1104 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001105 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001106 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001107 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1108 /* first clear the S_IFMT bits */
1109 result->st_mode ^= (result->st_mode & 0170000);
1110 /* now set the bits that make this a symlink */
1111 result->st_mode |= 0120000;
1112 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001113
Victor Stinner8c62be82010-05-06 00:08:46 +00001114 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001115}
1116
Guido van Rossumd8faa362007-04-27 19:54:29 +00001117static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001118attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001119{
Victor Stinner8c62be82010-05-06 00:08:46 +00001120 HANDLE hFindFile;
1121 WIN32_FIND_DATAA FileData;
1122 hFindFile = FindFirstFileA(pszFile, &FileData);
1123 if (hFindFile == INVALID_HANDLE_VALUE)
1124 return FALSE;
1125 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001126 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001127 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001128 info->dwFileAttributes = FileData.dwFileAttributes;
1129 info->ftCreationTime = FileData.ftCreationTime;
1130 info->ftLastAccessTime = FileData.ftLastAccessTime;
1131 info->ftLastWriteTime = FileData.ftLastWriteTime;
1132 info->nFileSizeHigh = FileData.nFileSizeHigh;
1133 info->nFileSizeLow = FileData.nFileSizeLow;
1134/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001135 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1136 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001137 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001138}
1139
1140static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001141attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001142{
Victor Stinner8c62be82010-05-06 00:08:46 +00001143 HANDLE hFindFile;
1144 WIN32_FIND_DATAW FileData;
1145 hFindFile = FindFirstFileW(pszFile, &FileData);
1146 if (hFindFile == INVALID_HANDLE_VALUE)
1147 return FALSE;
1148 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001149 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001150 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001151 info->dwFileAttributes = FileData.dwFileAttributes;
1152 info->ftCreationTime = FileData.ftCreationTime;
1153 info->ftLastAccessTime = FileData.ftLastAccessTime;
1154 info->ftLastWriteTime = FileData.ftLastWriteTime;
1155 info->nFileSizeHigh = FileData.nFileSizeHigh;
1156 info->nFileSizeLow = FileData.nFileSizeLow;
1157/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001158 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1159 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001160 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001161}
1162
Brian Curtind25aef52011-06-13 15:16:04 -05001163/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
1164static int has_GetFinalPathNameByHandle = 0;
Brian Curtind25aef52011-06-13 15:16:04 -05001165static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1166 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001167static int
Brian Curtind25aef52011-06-13 15:16:04 -05001168check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001169{
Brian Curtind25aef52011-06-13 15:16:04 -05001170 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001171 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1172 DWORD);
1173
Brian Curtind25aef52011-06-13 15:16:04 -05001174 /* only recheck */
1175 if (!has_GetFinalPathNameByHandle)
1176 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001177 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001178 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1179 "GetFinalPathNameByHandleA");
1180 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1181 "GetFinalPathNameByHandleW");
1182 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1183 Py_GetFinalPathNameByHandleW;
1184 }
1185 return has_GetFinalPathNameByHandle;
1186}
1187
1188static BOOL
1189get_target_path(HANDLE hdl, wchar_t **target_path)
1190{
1191 int buf_size, result_length;
1192 wchar_t *buf;
1193
1194 /* We have a good handle to the target, use it to determine
1195 the target path name (then we'll call lstat on it). */
1196 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1197 VOLUME_NAME_DOS);
1198 if(!buf_size)
1199 return FALSE;
1200
1201 buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001202 if (!buf) {
1203 SetLastError(ERROR_OUTOFMEMORY);
1204 return FALSE;
1205 }
1206
Brian Curtind25aef52011-06-13 15:16:04 -05001207 result_length = Py_GetFinalPathNameByHandleW(hdl,
1208 buf, buf_size, VOLUME_NAME_DOS);
1209
1210 if(!result_length) {
1211 free(buf);
1212 return FALSE;
1213 }
1214
1215 if(!CloseHandle(hdl)) {
1216 free(buf);
1217 return FALSE;
1218 }
1219
1220 buf[result_length] = 0;
1221
1222 *target_path = buf;
1223 return TRUE;
1224}
1225
1226static int
1227win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1228 BOOL traverse);
1229static int
1230win32_xstat_impl(const char *path, struct win32_stat *result,
1231 BOOL traverse)
1232{
Victor Stinner26de69d2011-06-17 15:15:38 +02001233 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001234 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001235 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001236 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001237 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001238 const char *dot;
1239
Brian Curtind25aef52011-06-13 15:16:04 -05001240 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001241 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1242 traverse reparse point. */
1243 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001244 }
1245
Brian Curtinf5e76d02010-11-24 13:14:05 +00001246 hFile = CreateFileA(
1247 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001248 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001249 0, /* share mode */
1250 NULL, /* security attributes */
1251 OPEN_EXISTING,
1252 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001253 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1254 Because of this, calls like GetFinalPathNameByHandle will return
1255 the symlink path agin and not the actual final path. */
1256 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1257 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001258 NULL);
1259
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001260 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001261 /* Either the target doesn't exist, or we don't have access to
1262 get a handle to it. If the former, we need to return an error.
1263 If the latter, we can use attributes_from_dir. */
1264 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001265 return -1;
1266 /* Could not get attributes on open file. Fall back to
1267 reading the directory. */
1268 if (!attributes_from_dir(path, &info, &reparse_tag))
1269 /* Very strange. This should not fail now */
1270 return -1;
1271 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1272 if (traverse) {
1273 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001274 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001275 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001276 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001277 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001278 } else {
1279 if (!GetFileInformationByHandle(hFile, &info)) {
1280 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001281 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001282 }
1283 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001284 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1285 return -1;
1286
1287 /* Close the outer open file handle now that we're about to
1288 reopen it with different flags. */
1289 if (!CloseHandle(hFile))
1290 return -1;
1291
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001292 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001293 /* In order to call GetFinalPathNameByHandle we need to open
1294 the file without the reparse handling flag set. */
1295 hFile2 = CreateFileA(
1296 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1297 NULL, OPEN_EXISTING,
1298 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1299 NULL);
1300 if (hFile2 == INVALID_HANDLE_VALUE)
1301 return -1;
1302
1303 if (!get_target_path(hFile2, &target_path))
1304 return -1;
1305
1306 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001307 free(target_path);
1308 return code;
1309 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001310 } else
1311 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001312 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001313 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001314
1315 /* Set S_IEXEC if it is an .exe, .bat, ... */
1316 dot = strrchr(path, '.');
1317 if (dot) {
1318 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1319 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1320 result->st_mode |= 0111;
1321 }
1322 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001323}
1324
1325static int
Brian Curtind25aef52011-06-13 15:16:04 -05001326win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1327 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001328{
1329 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001330 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001331 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001332 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001333 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001334 const wchar_t *dot;
1335
Brian Curtind25aef52011-06-13 15:16:04 -05001336 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001337 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1338 traverse reparse point. */
1339 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001340 }
1341
Brian Curtinf5e76d02010-11-24 13:14:05 +00001342 hFile = CreateFileW(
1343 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001344 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001345 0, /* share mode */
1346 NULL, /* security attributes */
1347 OPEN_EXISTING,
1348 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001349 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1350 Because of this, calls like GetFinalPathNameByHandle will return
1351 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001352 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001353 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001354 NULL);
1355
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001356 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001357 /* Either the target doesn't exist, or we don't have access to
1358 get a handle to it. If the former, we need to return an error.
1359 If the latter, we can use attributes_from_dir. */
1360 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001361 return -1;
1362 /* Could not get attributes on open file. Fall back to
1363 reading the directory. */
1364 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1365 /* Very strange. This should not fail now */
1366 return -1;
1367 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1368 if (traverse) {
1369 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001370 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001371 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001372 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001373 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001374 } else {
1375 if (!GetFileInformationByHandle(hFile, &info)) {
1376 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001377 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001378 }
1379 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001380 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1381 return -1;
1382
1383 /* Close the outer open file handle now that we're about to
1384 reopen it with different flags. */
1385 if (!CloseHandle(hFile))
1386 return -1;
1387
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001388 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001389 /* In order to call GetFinalPathNameByHandle we need to open
1390 the file without the reparse handling flag set. */
1391 hFile2 = CreateFileW(
1392 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1393 NULL, OPEN_EXISTING,
1394 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1395 NULL);
1396 if (hFile2 == INVALID_HANDLE_VALUE)
1397 return -1;
1398
1399 if (!get_target_path(hFile2, &target_path))
1400 return -1;
1401
1402 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001403 free(target_path);
1404 return code;
1405 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001406 } else
1407 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001408 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001409 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001410
1411 /* Set S_IEXEC if it is an .exe, .bat, ... */
1412 dot = wcsrchr(path, '.');
1413 if (dot) {
1414 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1415 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1416 result->st_mode |= 0111;
1417 }
1418 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001419}
1420
1421static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001422win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001423{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001424 /* Protocol violation: we explicitly clear errno, instead of
1425 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001426 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001427 errno = 0;
1428 return code;
1429}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001430
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001431static int
1432win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1433{
1434 /* Protocol violation: we explicitly clear errno, instead of
1435 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001436 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001437 errno = 0;
1438 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001439}
Brian Curtind25aef52011-06-13 15:16:04 -05001440/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001441
1442 In Posix, stat automatically traverses symlinks and returns the stat
1443 structure for the target. In Windows, the equivalent GetFileAttributes by
1444 default does not traverse symlinks and instead returns attributes for
1445 the symlink.
1446
1447 Therefore, win32_lstat will get the attributes traditionally, and
1448 win32_stat will first explicitly resolve the symlink target and then will
1449 call win32_lstat on that result.
1450
Ezio Melotti4969f702011-03-15 05:59:46 +02001451 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001452
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001453static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001454win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001455{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001456 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001457}
1458
Victor Stinner8c62be82010-05-06 00:08:46 +00001459static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001460win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001461{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001462 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001463}
1464
1465static int
1466win32_stat(const char* path, struct win32_stat *result)
1467{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001468 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001469}
1470
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001471static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001472win32_stat_w(const wchar_t* path, struct win32_stat *result)
1473{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001474 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001475}
1476
1477static int
1478win32_fstat(int file_number, struct win32_stat *result)
1479{
Victor Stinner8c62be82010-05-06 00:08:46 +00001480 BY_HANDLE_FILE_INFORMATION info;
1481 HANDLE h;
1482 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001483
Victor Stinner8c62be82010-05-06 00:08:46 +00001484 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001485
Victor Stinner8c62be82010-05-06 00:08:46 +00001486 /* Protocol violation: we explicitly clear errno, instead of
1487 setting it to a POSIX error. Callers should use GetLastError. */
1488 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001489
Victor Stinner8c62be82010-05-06 00:08:46 +00001490 if (h == INVALID_HANDLE_VALUE) {
1491 /* This is really a C library error (invalid file handle).
1492 We set the Win32 error to the closes one matching. */
1493 SetLastError(ERROR_INVALID_HANDLE);
1494 return -1;
1495 }
1496 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001497
Victor Stinner8c62be82010-05-06 00:08:46 +00001498 type = GetFileType(h);
1499 if (type == FILE_TYPE_UNKNOWN) {
1500 DWORD error = GetLastError();
1501 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001502 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001503 }
1504 /* else: valid but unknown file */
1505 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001506
Victor Stinner8c62be82010-05-06 00:08:46 +00001507 if (type != FILE_TYPE_DISK) {
1508 if (type == FILE_TYPE_CHAR)
1509 result->st_mode = _S_IFCHR;
1510 else if (type == FILE_TYPE_PIPE)
1511 result->st_mode = _S_IFIFO;
1512 return 0;
1513 }
1514
1515 if (!GetFileInformationByHandle(h, &info)) {
1516 return -1;
1517 }
1518
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001519 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001520 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001521 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1522 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001523}
1524
1525#endif /* MS_WINDOWS */
1526
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001527PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001528"stat_result: Result from stat or lstat.\n\n\
1529This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001530 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001531or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1532\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001533Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1534or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001535\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001536See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001537
1538static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001539 {"st_mode", "protection bits"},
1540 {"st_ino", "inode"},
1541 {"st_dev", "device"},
1542 {"st_nlink", "number of hard links"},
1543 {"st_uid", "user ID of owner"},
1544 {"st_gid", "group ID of owner"},
1545 {"st_size", "total size, in bytes"},
1546 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1547 {NULL, "integer time of last access"},
1548 {NULL, "integer time of last modification"},
1549 {NULL, "integer time of last change"},
1550 {"st_atime", "time of last access"},
1551 {"st_mtime", "time of last modification"},
1552 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001553#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001554 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001555#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001556#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001557 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001558#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001559#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001560 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001561#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001562#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001563 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001564#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001565#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001566 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001567#endif
1568#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001569 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001570#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001571 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001572};
1573
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001574#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001575#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001576#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001577#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001578#endif
1579
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001580#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001581#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1582#else
1583#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1584#endif
1585
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001586#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001587#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1588#else
1589#define ST_RDEV_IDX ST_BLOCKS_IDX
1590#endif
1591
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001592#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1593#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1594#else
1595#define ST_FLAGS_IDX ST_RDEV_IDX
1596#endif
1597
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001598#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001599#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001600#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001601#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001602#endif
1603
1604#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1605#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1606#else
1607#define ST_BIRTHTIME_IDX ST_GEN_IDX
1608#endif
1609
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001610static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001611 "stat_result", /* name */
1612 stat_result__doc__, /* doc */
1613 stat_result_fields,
1614 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001615};
1616
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001617PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001618"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1619This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001620 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001621or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001622\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001623See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001624
1625static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001626 {"f_bsize", },
1627 {"f_frsize", },
1628 {"f_blocks", },
1629 {"f_bfree", },
1630 {"f_bavail", },
1631 {"f_files", },
1632 {"f_ffree", },
1633 {"f_favail", },
1634 {"f_flag", },
1635 {"f_namemax",},
1636 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001637};
1638
1639static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001640 "statvfs_result", /* name */
1641 statvfs_result__doc__, /* doc */
1642 statvfs_result_fields,
1643 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001644};
1645
Ross Lagerwall7807c352011-03-17 20:20:30 +02001646#if defined(HAVE_WAITID) && !defined(__APPLE__)
1647PyDoc_STRVAR(waitid_result__doc__,
1648"waitid_result: Result from waitid.\n\n\
1649This object may be accessed either as a tuple of\n\
1650 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1651or via the attributes si_pid, si_uid, and so on.\n\
1652\n\
1653See os.waitid for more information.");
1654
1655static PyStructSequence_Field waitid_result_fields[] = {
1656 {"si_pid", },
1657 {"si_uid", },
1658 {"si_signo", },
1659 {"si_status", },
1660 {"si_code", },
1661 {0}
1662};
1663
1664static PyStructSequence_Desc waitid_result_desc = {
1665 "waitid_result", /* name */
1666 waitid_result__doc__, /* doc */
1667 waitid_result_fields,
1668 5
1669};
1670static PyTypeObject WaitidResultType;
1671#endif
1672
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001673static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001674static PyTypeObject StatResultType;
1675static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001676#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001677static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001678#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001679static newfunc structseq_new;
1680
1681static PyObject *
1682statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1683{
Victor Stinner8c62be82010-05-06 00:08:46 +00001684 PyStructSequence *result;
1685 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001686
Victor Stinner8c62be82010-05-06 00:08:46 +00001687 result = (PyStructSequence*)structseq_new(type, args, kwds);
1688 if (!result)
1689 return NULL;
1690 /* If we have been initialized from a tuple,
1691 st_?time might be set to None. Initialize it
1692 from the int slots. */
1693 for (i = 7; i <= 9; i++) {
1694 if (result->ob_item[i+3] == Py_None) {
1695 Py_DECREF(Py_None);
1696 Py_INCREF(result->ob_item[i]);
1697 result->ob_item[i+3] = result->ob_item[i];
1698 }
1699 }
1700 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001701}
1702
1703
1704
1705/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001706static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001707
1708PyDoc_STRVAR(stat_float_times__doc__,
1709"stat_float_times([newval]) -> oldval\n\n\
1710Determine whether os.[lf]stat represents time stamps as float objects.\n\
1711If newval is True, future calls to stat() return floats, if it is False,\n\
1712future calls return ints. \n\
1713If newval is omitted, return the current setting.\n");
1714
1715static PyObject*
1716stat_float_times(PyObject* self, PyObject *args)
1717{
Victor Stinner8c62be82010-05-06 00:08:46 +00001718 int newval = -1;
1719 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1720 return NULL;
1721 if (newval == -1)
1722 /* Return old value */
1723 return PyBool_FromLong(_stat_float_times);
1724 _stat_float_times = newval;
1725 Py_INCREF(Py_None);
1726 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001727}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001728
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001729static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001730fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001731{
Victor Stinner8c62be82010-05-06 00:08:46 +00001732 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001733#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinner8c62be82010-05-06 00:08:46 +00001734 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001735#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001736 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001737#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001738 if (!ival)
1739 return;
Victor Stinner4195b5c2012-02-08 23:03:19 +01001740 if (_stat_float_times) {
1741 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1742 } else {
Victor Stinner8c62be82010-05-06 00:08:46 +00001743 fval = ival;
1744 Py_INCREF(fval);
1745 }
1746 PyStructSequence_SET_ITEM(v, index, ival);
1747 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001748}
1749
Tim Peters5aa91602002-01-30 05:46:57 +00001750/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001751 (used by posix_stat() and posix_fstat()) */
1752static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001753_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001754{
Victor Stinner8c62be82010-05-06 00:08:46 +00001755 unsigned long ansec, mnsec, cnsec;
1756 PyObject *v = PyStructSequence_New(&StatResultType);
1757 if (v == NULL)
1758 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001759
Victor Stinner8c62be82010-05-06 00:08:46 +00001760 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001761#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001762 PyStructSequence_SET_ITEM(v, 1,
1763 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001764#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001765 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001766#endif
1767#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001768 PyStructSequence_SET_ITEM(v, 2,
1769 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001770#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001771 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001772#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001773 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1774 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1775 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001776#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001777 PyStructSequence_SET_ITEM(v, 6,
1778 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001779#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001780 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001781#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001782
Martin v. Löwis14694662006-02-03 12:54:16 +00001783#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001784 ansec = st->st_atim.tv_nsec;
1785 mnsec = st->st_mtim.tv_nsec;
1786 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001787#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001788 ansec = st->st_atimespec.tv_nsec;
1789 mnsec = st->st_mtimespec.tv_nsec;
1790 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001791#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001792 ansec = st->st_atime_nsec;
1793 mnsec = st->st_mtime_nsec;
1794 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001795#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001796 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001797#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01001798 fill_time(v, 7, st->st_atime, ansec);
1799 fill_time(v, 8, st->st_mtime, mnsec);
1800 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001801
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001802#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001803 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1804 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001805#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001806#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001807 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1808 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001809#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001810#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001811 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1812 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001813#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001814#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001815 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1816 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001817#endif
1818#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001819 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01001820 PyObject *val;
1821 unsigned long bsec,bnsec;
1822 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001823#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01001824 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001825#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01001826 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001827#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01001828 if (_stat_float_times) {
1829 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1830 } else {
1831 val = PyLong_FromLong((long)bsec);
1832 }
1833 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1834 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00001835 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001836#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001837#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001838 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1839 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001840#endif
Fred Drake699f3522000-06-29 21:12:41 +00001841
Victor Stinner8c62be82010-05-06 00:08:46 +00001842 if (PyErr_Occurred()) {
1843 Py_DECREF(v);
1844 return NULL;
1845 }
Fred Drake699f3522000-06-29 21:12:41 +00001846
Victor Stinner8c62be82010-05-06 00:08:46 +00001847 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001848}
1849
Barry Warsaw53699e91996-12-10 23:23:01 +00001850static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01001851posix_do_stat(PyObject *self, PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +00001852 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001853#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00001854 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001855#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001856 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001857#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001858 char *wformat,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001859 int (*wstatfunc)(const wchar_t *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001860{
Victor Stinner8c62be82010-05-06 00:08:46 +00001861 STRUCT_STAT st;
1862 PyObject *opath;
1863 char *path;
1864 int res;
1865 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001866
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001867#ifdef MS_WINDOWS
Victor Stinnereb5657a2011-09-30 01:44:27 +02001868 PyObject *po;
Victor Stinner4195b5c2012-02-08 23:03:19 +01001869 if (PyArg_ParseTuple(args, wformat, &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02001870 wchar_t *wpath = PyUnicode_AsUnicode(po);
1871 if (wpath == NULL)
1872 return NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00001873
Victor Stinner8c62be82010-05-06 00:08:46 +00001874 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00001875 res = wstatfunc(wpath, &st);
1876 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001877
Victor Stinner8c62be82010-05-06 00:08:46 +00001878 if (res != 0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001879 return win32_error_object("stat", po);
Victor Stinner4195b5c2012-02-08 23:03:19 +01001880 return _pystat_fromstructstat(&st);
Victor Stinner8c62be82010-05-06 00:08:46 +00001881 }
1882 /* Drop the argument parsing error as narrow strings
1883 are also valid. */
1884 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001885#endif
1886
Victor Stinner4195b5c2012-02-08 23:03:19 +01001887 if (!PyArg_ParseTuple(args, format,
1888 PyUnicode_FSConverter, &opath))
Victor Stinner8c62be82010-05-06 00:08:46 +00001889 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001890#ifdef MS_WINDOWS
1891 if (win32_warn_bytes_api()) {
1892 Py_DECREF(opath);
1893 return NULL;
1894 }
1895#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001896 path = PyBytes_AsString(opath);
1897 Py_BEGIN_ALLOW_THREADS
1898 res = (*statfunc)(path, &st);
1899 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001900
Victor Stinner8c62be82010-05-06 00:08:46 +00001901 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001902#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001903 result = win32_error("stat", path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001904#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001905 result = posix_error_with_filename(path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001906#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001907 }
1908 else
Victor Stinner4195b5c2012-02-08 23:03:19 +01001909 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001910
Victor Stinner8c62be82010-05-06 00:08:46 +00001911 Py_DECREF(opath);
1912 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001913}
1914
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001915/* POSIX methods */
1916
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001917PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001918"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001919Use the real uid/gid to test for access to a path. Note that most\n\
1920operations will use the effective uid/gid, therefore this routine can\n\
1921be used in a suid/sgid environment to test if the invoking user has the\n\
1922specified access to the path. The mode argument can be F_OK to test\n\
1923existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001924
1925static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001926posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001927{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001928 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001929 int mode;
1930
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001931#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001932 DWORD attr;
Victor Stinnereb5657a2011-09-30 01:44:27 +02001933 PyObject *po;
Victor Stinner8c62be82010-05-06 00:08:46 +00001934 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02001935 wchar_t* wpath = PyUnicode_AsUnicode(po);
1936 if (wpath == NULL)
1937 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001938 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02001939 attr = GetFileAttributesW(wpath);
Victor Stinner8c62be82010-05-06 00:08:46 +00001940 Py_END_ALLOW_THREADS
1941 goto finish;
1942 }
1943 /* Drop the argument parsing error as narrow strings
1944 are also valid. */
1945 PyErr_Clear();
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001946 if (!PyArg_ParseTuple(args, "yi:access", &path, &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00001947 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001948 if (win32_warn_bytes_api())
1949 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001950 Py_BEGIN_ALLOW_THREADS
1951 attr = GetFileAttributesA(path);
1952 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001953finish:
Victor Stinner8c62be82010-05-06 00:08:46 +00001954 if (attr == 0xFFFFFFFF)
1955 /* File does not exist, or cannot read attributes */
1956 return PyBool_FromLong(0);
1957 /* Access is possible if either write access wasn't requested, or
1958 the file isn't read-only, or if it's a directory, as there are
1959 no read-only directories on Windows. */
1960 return PyBool_FromLong(!(mode & 2)
1961 || !(attr & FILE_ATTRIBUTE_READONLY)
1962 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001963#else
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001964 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00001965 int res;
1966 if (!PyArg_ParseTuple(args, "O&i:access",
1967 PyUnicode_FSConverter, &opath, &mode))
1968 return NULL;
1969 path = PyBytes_AsString(opath);
1970 Py_BEGIN_ALLOW_THREADS
1971 res = access(path, mode);
1972 Py_END_ALLOW_THREADS
1973 Py_DECREF(opath);
1974 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001975#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001976}
1977
Guido van Rossumd371ff11999-01-25 16:12:23 +00001978#ifndef F_OK
1979#define F_OK 0
1980#endif
1981#ifndef R_OK
1982#define R_OK 4
1983#endif
1984#ifndef W_OK
1985#define W_OK 2
1986#endif
1987#ifndef X_OK
1988#define X_OK 1
1989#endif
1990
1991#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001992PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001993"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001994Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001995
1996static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001997posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001998{
Victor Stinner8c62be82010-05-06 00:08:46 +00001999 int id;
2000 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002001
Victor Stinner8c62be82010-05-06 00:08:46 +00002002 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
2003 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002004
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002005#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002006 /* file descriptor 0 only, the default input device (stdin) */
2007 if (id == 0) {
2008 ret = ttyname();
2009 }
2010 else {
2011 ret = NULL;
2012 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002013#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002014 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002015#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002016 if (ret == NULL)
2017 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002018 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002019}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002020#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002021
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002022#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002023PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002024"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002025Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002026
2027static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002028posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002029{
Victor Stinner8c62be82010-05-06 00:08:46 +00002030 char *ret;
2031 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002032
Greg Wardb48bc172000-03-01 21:51:56 +00002033#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002034 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002035#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002036 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002037#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002038 if (ret == NULL)
2039 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002040 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002041}
2042#endif
2043
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002044PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002045"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002046Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002047
Barry Warsaw53699e91996-12-10 23:23:01 +00002048static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002049posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002050{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002051#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002052 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002053#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002054 return posix_1str(args, "O&:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00002055#elif defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002056 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002057#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002058 return posix_1str(args, "O&:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002059#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002060}
2061
Fred Drake4d1e64b2002-04-15 19:40:07 +00002062#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002063PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002064"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00002065Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002066opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002067
2068static PyObject *
2069posix_fchdir(PyObject *self, PyObject *fdobj)
2070{
Victor Stinner8c62be82010-05-06 00:08:46 +00002071 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002072}
2073#endif /* HAVE_FCHDIR */
2074
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002075
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002076PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002077"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002078Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002079
Barry Warsaw53699e91996-12-10 23:23:01 +00002080static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002081posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002082{
Victor Stinner8c62be82010-05-06 00:08:46 +00002083 PyObject *opath = NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002084 const char *path = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002085 int i;
2086 int res;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002087#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002088 DWORD attr;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002089 PyObject *po;
Victor Stinner8c62be82010-05-06 00:08:46 +00002090 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02002091 wchar_t *wpath = PyUnicode_AsUnicode(po);
2092 if (wpath == NULL)
2093 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002094 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02002095 attr = GetFileAttributesW(wpath);
Victor Stinner8c62be82010-05-06 00:08:46 +00002096 if (attr != 0xFFFFFFFF) {
2097 if (i & _S_IWRITE)
2098 attr &= ~FILE_ATTRIBUTE_READONLY;
2099 else
2100 attr |= FILE_ATTRIBUTE_READONLY;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002101 res = SetFileAttributesW(wpath, attr);
Victor Stinner8c62be82010-05-06 00:08:46 +00002102 }
2103 else
2104 res = 0;
2105 Py_END_ALLOW_THREADS
2106 if (!res)
Victor Stinnereb5657a2011-09-30 01:44:27 +02002107 return win32_error_object("chmod", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00002108 Py_INCREF(Py_None);
2109 return Py_None;
2110 }
2111 /* Drop the argument parsing error as narrow strings
2112 are also valid. */
2113 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002114
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002115 if (!PyArg_ParseTuple(args, "yi:chmod", &path, &i))
Victor Stinner8c62be82010-05-06 00:08:46 +00002116 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002117 if (win32_warn_bytes_api())
2118 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002119 Py_BEGIN_ALLOW_THREADS
2120 attr = GetFileAttributesA(path);
2121 if (attr != 0xFFFFFFFF) {
2122 if (i & _S_IWRITE)
2123 attr &= ~FILE_ATTRIBUTE_READONLY;
2124 else
2125 attr |= FILE_ATTRIBUTE_READONLY;
2126 res = SetFileAttributesA(path, attr);
2127 }
2128 else
2129 res = 0;
2130 Py_END_ALLOW_THREADS
2131 if (!res) {
2132 win32_error("chmod", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00002133 return NULL;
2134 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002135 Py_INCREF(Py_None);
2136 return Py_None;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002137#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00002138 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
2139 &opath, &i))
2140 return NULL;
2141 path = PyBytes_AsString(opath);
2142 Py_BEGIN_ALLOW_THREADS
2143 res = chmod(path, i);
2144 Py_END_ALLOW_THREADS
2145 if (res < 0)
2146 return posix_error_with_allocated_filename(opath);
2147 Py_DECREF(opath);
2148 Py_INCREF(Py_None);
2149 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002150#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002151}
2152
Christian Heimes4e30a842007-11-30 22:12:06 +00002153#ifdef HAVE_FCHMOD
2154PyDoc_STRVAR(posix_fchmod__doc__,
2155"fchmod(fd, mode)\n\n\
2156Change the access permissions of the file given by file\n\
2157descriptor fd.");
2158
2159static PyObject *
2160posix_fchmod(PyObject *self, PyObject *args)
2161{
Victor Stinner8c62be82010-05-06 00:08:46 +00002162 int fd, mode, res;
2163 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2164 return NULL;
2165 Py_BEGIN_ALLOW_THREADS
2166 res = fchmod(fd, mode);
2167 Py_END_ALLOW_THREADS
2168 if (res < 0)
2169 return posix_error();
2170 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002171}
2172#endif /* HAVE_FCHMOD */
2173
2174#ifdef HAVE_LCHMOD
2175PyDoc_STRVAR(posix_lchmod__doc__,
2176"lchmod(path, mode)\n\n\
2177Change the access permissions of a file. If path is a symlink, this\n\
2178affects the link itself rather than the target.");
2179
2180static PyObject *
2181posix_lchmod(PyObject *self, PyObject *args)
2182{
Victor Stinner8c62be82010-05-06 00:08:46 +00002183 PyObject *opath;
2184 char *path;
2185 int i;
2186 int res;
2187 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
2188 &opath, &i))
2189 return NULL;
2190 path = PyBytes_AsString(opath);
2191 Py_BEGIN_ALLOW_THREADS
2192 res = lchmod(path, i);
2193 Py_END_ALLOW_THREADS
2194 if (res < 0)
2195 return posix_error_with_allocated_filename(opath);
2196 Py_DECREF(opath);
2197 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002198}
2199#endif /* HAVE_LCHMOD */
2200
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002201
Thomas Wouterscf297e42007-02-23 15:07:44 +00002202#ifdef HAVE_CHFLAGS
2203PyDoc_STRVAR(posix_chflags__doc__,
2204"chflags(path, flags)\n\n\
2205Set file flags.");
2206
2207static PyObject *
2208posix_chflags(PyObject *self, PyObject *args)
2209{
Victor Stinner8c62be82010-05-06 00:08:46 +00002210 PyObject *opath;
2211 char *path;
2212 unsigned long flags;
2213 int res;
2214 if (!PyArg_ParseTuple(args, "O&k:chflags",
2215 PyUnicode_FSConverter, &opath, &flags))
2216 return NULL;
2217 path = PyBytes_AsString(opath);
2218 Py_BEGIN_ALLOW_THREADS
2219 res = chflags(path, flags);
2220 Py_END_ALLOW_THREADS
2221 if (res < 0)
2222 return posix_error_with_allocated_filename(opath);
2223 Py_DECREF(opath);
2224 Py_INCREF(Py_None);
2225 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002226}
2227#endif /* HAVE_CHFLAGS */
2228
2229#ifdef HAVE_LCHFLAGS
2230PyDoc_STRVAR(posix_lchflags__doc__,
2231"lchflags(path, flags)\n\n\
2232Set file flags.\n\
2233This function will not follow symbolic links.");
2234
2235static PyObject *
2236posix_lchflags(PyObject *self, PyObject *args)
2237{
Victor Stinner8c62be82010-05-06 00:08:46 +00002238 PyObject *opath;
2239 char *path;
2240 unsigned long flags;
2241 int res;
2242 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2243 PyUnicode_FSConverter, &opath, &flags))
2244 return NULL;
2245 path = PyBytes_AsString(opath);
2246 Py_BEGIN_ALLOW_THREADS
2247 res = lchflags(path, flags);
2248 Py_END_ALLOW_THREADS
2249 if (res < 0)
2250 return posix_error_with_allocated_filename(opath);
2251 Py_DECREF(opath);
2252 Py_INCREF(Py_None);
2253 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002254}
2255#endif /* HAVE_LCHFLAGS */
2256
Martin v. Löwis244edc82001-10-04 22:44:26 +00002257#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002258PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002259"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002260Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002261
2262static PyObject *
2263posix_chroot(PyObject *self, PyObject *args)
2264{
Victor Stinner8c62be82010-05-06 00:08:46 +00002265 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002266}
2267#endif
2268
Guido van Rossum21142a01999-01-08 21:05:37 +00002269#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002270PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002271"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002272force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002273
2274static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002275posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002276{
Stefan Krah0e803b32010-11-26 16:16:47 +00002277 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002278}
2279#endif /* HAVE_FSYNC */
2280
Ross Lagerwall7807c352011-03-17 20:20:30 +02002281#ifdef HAVE_SYNC
2282PyDoc_STRVAR(posix_sync__doc__,
2283"sync()\n\n\
2284Force write of everything to disk.");
2285
2286static PyObject *
2287posix_sync(PyObject *self, PyObject *noargs)
2288{
2289 Py_BEGIN_ALLOW_THREADS
2290 sync();
2291 Py_END_ALLOW_THREADS
2292 Py_RETURN_NONE;
2293}
2294#endif
2295
Guido van Rossum21142a01999-01-08 21:05:37 +00002296#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002297
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002298#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002299extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2300#endif
2301
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002302PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002303"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002304force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002305 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002306
2307static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002308posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002309{
Stefan Krah0e803b32010-11-26 16:16:47 +00002310 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002311}
2312#endif /* HAVE_FDATASYNC */
2313
2314
Fredrik Lundh10723342000-07-10 16:38:09 +00002315#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002316PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002317"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002318Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002319
Barry Warsaw53699e91996-12-10 23:23:01 +00002320static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002321posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002322{
Victor Stinner8c62be82010-05-06 00:08:46 +00002323 PyObject *opath;
2324 char *path;
2325 long uid, gid;
2326 int res;
2327 if (!PyArg_ParseTuple(args, "O&ll:chown",
2328 PyUnicode_FSConverter, &opath,
2329 &uid, &gid))
2330 return NULL;
2331 path = PyBytes_AsString(opath);
2332 Py_BEGIN_ALLOW_THREADS
2333 res = chown(path, (uid_t) uid, (gid_t) gid);
2334 Py_END_ALLOW_THREADS
2335 if (res < 0)
2336 return posix_error_with_allocated_filename(opath);
2337 Py_DECREF(opath);
2338 Py_INCREF(Py_None);
2339 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002340}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002341#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002342
Christian Heimes4e30a842007-11-30 22:12:06 +00002343#ifdef HAVE_FCHOWN
2344PyDoc_STRVAR(posix_fchown__doc__,
2345"fchown(fd, uid, gid)\n\n\
2346Change the owner and group id of the file given by file descriptor\n\
2347fd to the numeric uid and gid.");
2348
2349static PyObject *
2350posix_fchown(PyObject *self, PyObject *args)
2351{
Victor Stinner8c62be82010-05-06 00:08:46 +00002352 int fd;
2353 long uid, gid;
2354 int res;
Victor Stinner26de69d2011-06-17 15:15:38 +02002355 if (!PyArg_ParseTuple(args, "ill:fchown", &fd, &uid, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00002356 return NULL;
2357 Py_BEGIN_ALLOW_THREADS
2358 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2359 Py_END_ALLOW_THREADS
2360 if (res < 0)
2361 return posix_error();
2362 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002363}
2364#endif /* HAVE_FCHOWN */
2365
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002366#ifdef HAVE_LCHOWN
2367PyDoc_STRVAR(posix_lchown__doc__,
2368"lchown(path, uid, gid)\n\n\
2369Change the owner and group id of path to the numeric uid and gid.\n\
2370This function will not follow symbolic links.");
2371
2372static PyObject *
2373posix_lchown(PyObject *self, PyObject *args)
2374{
Victor Stinner8c62be82010-05-06 00:08:46 +00002375 PyObject *opath;
2376 char *path;
2377 long uid, gid;
2378 int res;
2379 if (!PyArg_ParseTuple(args, "O&ll:lchown",
2380 PyUnicode_FSConverter, &opath,
2381 &uid, &gid))
2382 return NULL;
2383 path = PyBytes_AsString(opath);
2384 Py_BEGIN_ALLOW_THREADS
2385 res = lchown(path, (uid_t) uid, (gid_t) gid);
2386 Py_END_ALLOW_THREADS
2387 if (res < 0)
2388 return posix_error_with_allocated_filename(opath);
2389 Py_DECREF(opath);
2390 Py_INCREF(Py_None);
2391 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002392}
2393#endif /* HAVE_LCHOWN */
2394
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002395
Guido van Rossum36bc6801995-06-14 22:54:23 +00002396#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002397static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002398posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002399{
Victor Stinner8c62be82010-05-06 00:08:46 +00002400 char buf[1026];
2401 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002402
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002403#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002404 if (!use_bytes) {
2405 wchar_t wbuf[1026];
2406 wchar_t *wbuf2 = wbuf;
2407 PyObject *resobj;
2408 DWORD len;
2409 Py_BEGIN_ALLOW_THREADS
2410 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2411 /* If the buffer is large enough, len does not include the
2412 terminating \0. If the buffer is too small, len includes
2413 the space needed for the terminator. */
2414 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2415 wbuf2 = malloc(len * sizeof(wchar_t));
2416 if (wbuf2)
2417 len = GetCurrentDirectoryW(len, wbuf2);
2418 }
2419 Py_END_ALLOW_THREADS
2420 if (!wbuf2) {
2421 PyErr_NoMemory();
2422 return NULL;
2423 }
2424 if (!len) {
2425 if (wbuf2 != wbuf) free(wbuf2);
2426 return win32_error("getcwdu", NULL);
2427 }
2428 resobj = PyUnicode_FromWideChar(wbuf2, len);
2429 if (wbuf2 != wbuf) free(wbuf2);
2430 return resobj;
2431 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01002432
2433 if (win32_warn_bytes_api())
2434 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002435#endif
2436
Victor Stinner8c62be82010-05-06 00:08:46 +00002437 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002438#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002439 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002440#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002441 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002442#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002443 Py_END_ALLOW_THREADS
2444 if (res == NULL)
2445 return posix_error();
2446 if (use_bytes)
2447 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00002448 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002449}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002450
2451PyDoc_STRVAR(posix_getcwd__doc__,
2452"getcwd() -> path\n\n\
2453Return a unicode string representing the current working directory.");
2454
2455static PyObject *
2456posix_getcwd_unicode(PyObject *self)
2457{
2458 return posix_getcwd(0);
2459}
2460
2461PyDoc_STRVAR(posix_getcwdb__doc__,
2462"getcwdb() -> path\n\n\
2463Return a bytes string representing the current working directory.");
2464
2465static PyObject *
2466posix_getcwd_bytes(PyObject *self)
2467{
2468 return posix_getcwd(1);
2469}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002470#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002471
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002472
Guido van Rossumb6775db1994-08-01 11:34:53 +00002473#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002474PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002475"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002476Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002477
Barry Warsaw53699e91996-12-10 23:23:01 +00002478static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002479posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002480{
Victor Stinner8c62be82010-05-06 00:08:46 +00002481 return posix_2str(args, "O&O&:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002482}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002483#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002484
Brian Curtin1b9df392010-11-24 20:24:31 +00002485#ifdef MS_WINDOWS
2486PyDoc_STRVAR(win32_link__doc__,
2487"link(src, dst)\n\n\
2488Create a hard link to a file.");
2489
2490static PyObject *
2491win32_link(PyObject *self, PyObject *args)
2492{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002493 PyObject *src, *dst;
2494 BOOL ok;
Brian Curtin1b9df392010-11-24 20:24:31 +00002495
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002496 if (PyArg_ParseTuple(args, "UU:link", &src, &dst))
Victor Stinnereb5657a2011-09-30 01:44:27 +02002497 {
2498 wchar_t *wsrc, *wdst;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002499
2500 wsrc = PyUnicode_AsUnicode(src);
Victor Stinnereb5657a2011-09-30 01:44:27 +02002501 if (wsrc == NULL)
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002502 goto error;
2503 wdst = PyUnicode_AsUnicode(dst);
Victor Stinnereb5657a2011-09-30 01:44:27 +02002504 if (wdst == NULL)
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002505 goto error;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002506
Brian Curtinfc889c42010-11-28 23:59:46 +00002507 Py_BEGIN_ALLOW_THREADS
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002508 ok = CreateHardLinkW(wdst, wsrc, NULL);
Brian Curtinfc889c42010-11-28 23:59:46 +00002509 Py_END_ALLOW_THREADS
2510
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002511 if (!ok)
Brian Curtinfc889c42010-11-28 23:59:46 +00002512 return win32_error("link", NULL);
Brian Curtinfc889c42010-11-28 23:59:46 +00002513 Py_RETURN_NONE;
2514 }
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002515 else {
2516 PyErr_Clear();
2517 if (!PyArg_ParseTuple(args, "O&O&:link",
2518 PyUnicode_FSConverter, &src,
2519 PyUnicode_FSConverter, &dst))
2520 return NULL;
Brian Curtinfc889c42010-11-28 23:59:46 +00002521
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002522 if (win32_warn_bytes_api())
2523 goto error;
Brian Curtinfc889c42010-11-28 23:59:46 +00002524
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002525 Py_BEGIN_ALLOW_THREADS
2526 ok = CreateHardLinkA(PyBytes_AS_STRING(dst),
2527 PyBytes_AS_STRING(src),
2528 NULL);
2529 Py_END_ALLOW_THREADS
2530
2531 Py_XDECREF(src);
2532 Py_XDECREF(dst);
2533
2534 if (!ok)
2535 return win32_error("link", NULL);
2536 Py_RETURN_NONE;
2537
2538 error:
2539 Py_XDECREF(src);
2540 Py_XDECREF(dst);
Brian Curtin1b9df392010-11-24 20:24:31 +00002541 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002542 }
Brian Curtin1b9df392010-11-24 20:24:31 +00002543}
2544#endif /* MS_WINDOWS */
2545
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002546
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002547PyDoc_STRVAR(posix_listdir__doc__,
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002548"listdir([path]) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002549Return a list containing the names of the entries in the directory.\n\
2550\n\
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002551 path: path of directory to list (default: '.')\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002552\n\
2553The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002554entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002555
Barry Warsaw53699e91996-12-10 23:23:01 +00002556static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002557posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002558{
Victor Stinner8c62be82010-05-06 00:08:46 +00002559 /* XXX Should redo this putting the (now four) versions of opendir
2560 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002561#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002562
Victor Stinner8c62be82010-05-06 00:08:46 +00002563 PyObject *d, *v;
2564 HANDLE hFindFile;
2565 BOOL result;
2566 WIN32_FIND_DATA FileData;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002567 const char *path;
2568 Py_ssize_t pathlen;
Victor Stinner8c62be82010-05-06 00:08:46 +00002569 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2570 char *bufptr = namebuf;
2571 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002572
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002573 PyObject *po = NULL;
2574 if (PyArg_ParseTuple(args, "|U:listdir", &po)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002575 WIN32_FIND_DATAW wFileData;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002576 wchar_t *wnamebuf, *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002577
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002578 if (po == NULL) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002579 po_wchars = L".";
2580 len = 1;
2581 } else {
Victor Stinnerbeac78b2011-10-11 21:55:01 +02002582 po_wchars = PyUnicode_AsUnicodeAndSize(po, &len);
Victor Stinnereb5657a2011-09-30 01:44:27 +02002583 if (po_wchars == NULL)
2584 return NULL;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002585 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002586 /* Overallocate for \\*.*\0 */
Victor Stinner8c62be82010-05-06 00:08:46 +00002587 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2588 if (!wnamebuf) {
2589 PyErr_NoMemory();
2590 return NULL;
2591 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002592 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00002593 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02002594 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00002595 if (wch != L'/' && wch != L'\\' && wch != L':')
2596 wnamebuf[len++] = L'\\';
2597 wcscpy(wnamebuf + len, L"*.*");
2598 }
2599 if ((d = PyList_New(0)) == NULL) {
2600 free(wnamebuf);
2601 return NULL;
2602 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00002603 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002604 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002605 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002606 if (hFindFile == INVALID_HANDLE_VALUE) {
2607 int error = GetLastError();
2608 if (error == ERROR_FILE_NOT_FOUND) {
2609 free(wnamebuf);
2610 return d;
2611 }
2612 Py_DECREF(d);
2613 win32_error_unicode("FindFirstFileW", wnamebuf);
2614 free(wnamebuf);
2615 return NULL;
2616 }
2617 do {
2618 /* Skip over . and .. */
2619 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2620 wcscmp(wFileData.cFileName, L"..") != 0) {
Victor Stinner9d3b93b2011-11-22 02:27:30 +01002621 v = PyUnicode_FromWideChar(wFileData.cFileName, wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00002622 if (v == NULL) {
2623 Py_DECREF(d);
2624 d = NULL;
2625 break;
2626 }
2627 if (PyList_Append(d, v) != 0) {
2628 Py_DECREF(v);
2629 Py_DECREF(d);
2630 d = NULL;
2631 break;
2632 }
2633 Py_DECREF(v);
2634 }
2635 Py_BEGIN_ALLOW_THREADS
2636 result = FindNextFileW(hFindFile, &wFileData);
2637 Py_END_ALLOW_THREADS
2638 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2639 it got to the end of the directory. */
2640 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2641 Py_DECREF(d);
2642 win32_error_unicode("FindNextFileW", wnamebuf);
2643 FindClose(hFindFile);
2644 free(wnamebuf);
2645 return NULL;
2646 }
2647 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002648
Victor Stinner8c62be82010-05-06 00:08:46 +00002649 if (FindClose(hFindFile) == FALSE) {
2650 Py_DECREF(d);
2651 win32_error_unicode("FindClose", wnamebuf);
2652 free(wnamebuf);
2653 return NULL;
2654 }
2655 free(wnamebuf);
2656 return d;
2657 }
2658 /* Drop the argument parsing error as narrow strings
2659 are also valid. */
2660 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002661
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002662 if (!PyArg_ParseTuple(args, "y#:listdir", &path, &pathlen))
Victor Stinner8c62be82010-05-06 00:08:46 +00002663 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002664 if (win32_warn_bytes_api())
2665 return NULL;
2666 if (pathlen+1 > MAX_PATH) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002667 PyErr_SetString(PyExc_ValueError, "path too long");
Victor Stinner8c62be82010-05-06 00:08:46 +00002668 return NULL;
2669 }
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002670 strcpy(namebuf, path);
2671 len = pathlen;
Victor Stinner8c62be82010-05-06 00:08:46 +00002672 if (len > 0) {
2673 char ch = namebuf[len-1];
2674 if (ch != SEP && ch != ALTSEP && ch != ':')
2675 namebuf[len++] = '/';
2676 strcpy(namebuf + len, "*.*");
2677 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002678
Victor Stinner8c62be82010-05-06 00:08:46 +00002679 if ((d = PyList_New(0)) == NULL)
2680 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002681
Antoine Pitroub73caab2010-08-09 23:39:31 +00002682 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002683 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002684 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002685 if (hFindFile == INVALID_HANDLE_VALUE) {
2686 int error = GetLastError();
2687 if (error == ERROR_FILE_NOT_FOUND)
2688 return d;
2689 Py_DECREF(d);
2690 return win32_error("FindFirstFile", namebuf);
2691 }
2692 do {
2693 /* Skip over . and .. */
2694 if (strcmp(FileData.cFileName, ".") != 0 &&
2695 strcmp(FileData.cFileName, "..") != 0) {
2696 v = PyBytes_FromString(FileData.cFileName);
2697 if (v == NULL) {
2698 Py_DECREF(d);
2699 d = NULL;
2700 break;
2701 }
2702 if (PyList_Append(d, v) != 0) {
2703 Py_DECREF(v);
2704 Py_DECREF(d);
2705 d = NULL;
2706 break;
2707 }
2708 Py_DECREF(v);
2709 }
2710 Py_BEGIN_ALLOW_THREADS
2711 result = FindNextFile(hFindFile, &FileData);
2712 Py_END_ALLOW_THREADS
2713 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2714 it got to the end of the directory. */
2715 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2716 Py_DECREF(d);
2717 win32_error("FindNextFile", namebuf);
2718 FindClose(hFindFile);
2719 return NULL;
2720 }
2721 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002722
Victor Stinner8c62be82010-05-06 00:08:46 +00002723 if (FindClose(hFindFile) == FALSE) {
2724 Py_DECREF(d);
2725 return win32_error("FindClose", namebuf);
2726 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002727
Victor Stinner8c62be82010-05-06 00:08:46 +00002728 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002729
Tim Peters0bb44a42000-09-15 07:44:49 +00002730#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002731
2732#ifndef MAX_PATH
2733#define MAX_PATH CCHMAXPATH
2734#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002735 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002736 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002737 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002738 PyObject *d, *v;
2739 char namebuf[MAX_PATH+5];
2740 HDIR hdir = 1;
2741 ULONG srchcnt = 1;
2742 FILEFINDBUF3 ep;
2743 APIRET rc;
2744
Victor Stinner8c62be82010-05-06 00:08:46 +00002745 if (!PyArg_ParseTuple(args, "O&:listdir",
Martin v. Löwis011e8422009-05-05 04:43:17 +00002746 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002747 return NULL;
Victor Stinnerdcb24032010-04-22 12:08:36 +00002748 name = PyBytes_AsString(oname);
2749 len = PyBytes_GET_SIZE(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002750 if (len >= MAX_PATH) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002751 Py_DECREF(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002752 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002753 return NULL;
2754 }
2755 strcpy(namebuf, name);
2756 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002757 if (*pt == ALTSEP)
2758 *pt = SEP;
2759 if (namebuf[len-1] != SEP)
2760 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002761 strcpy(namebuf + len, "*.*");
2762
Neal Norwitz6c913782007-10-14 03:23:09 +00002763 if ((d = PyList_New(0)) == NULL) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002764 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002765 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002766 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002767
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002768 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2769 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002770 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002771 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2772 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2773 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002774
2775 if (rc != NO_ERROR) {
2776 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002777 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002778 }
2779
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002780 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002781 do {
2782 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002783 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002784 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002785
2786 strcpy(namebuf, ep.achName);
2787
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002788 /* Leave Case of Name Alone -- In Native Form */
2789 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002790
Christian Heimes72b710a2008-05-26 13:28:38 +00002791 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002792 if (v == NULL) {
2793 Py_DECREF(d);
2794 d = NULL;
2795 break;
2796 }
2797 if (PyList_Append(d, v) != 0) {
2798 Py_DECREF(v);
2799 Py_DECREF(d);
2800 d = NULL;
2801 break;
2802 }
2803 Py_DECREF(v);
2804 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2805 }
2806
Victor Stinnerdcb24032010-04-22 12:08:36 +00002807 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002808 return d;
2809#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002810 PyObject *oname;
2811 char *name;
2812 PyObject *d, *v;
2813 DIR *dirp;
2814 struct dirent *ep;
2815 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002816
Victor Stinner8c62be82010-05-06 00:08:46 +00002817 errno = 0;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002818 /* v is never read, so it does not need to be initialized yet. */
2819 if (!PyArg_ParseTuple(args, "|U:listdir", &v)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002820 arg_is_unicode = 0;
2821 PyErr_Clear();
2822 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002823 oname = NULL;
2824 if (!PyArg_ParseTuple(args, "|O&:listdir", PyUnicode_FSConverter, &oname))
Victor Stinner8c62be82010-05-06 00:08:46 +00002825 return NULL;
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002826 if (oname == NULL) { /* Default arg: "." */
Stefan Krah0e803b32010-11-26 16:16:47 +00002827 oname = PyBytes_FromString(".");
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002828 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002829 name = PyBytes_AsString(oname);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002830 Py_BEGIN_ALLOW_THREADS
2831 dirp = opendir(name);
2832 Py_END_ALLOW_THREADS
2833 if (dirp == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002834 return posix_error_with_allocated_filename(oname);
2835 }
2836 if ((d = PyList_New(0)) == NULL) {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002837 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002838 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002839 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002840 Py_DECREF(oname);
2841 return NULL;
2842 }
2843 for (;;) {
2844 errno = 0;
2845 Py_BEGIN_ALLOW_THREADS
2846 ep = readdir(dirp);
2847 Py_END_ALLOW_THREADS
2848 if (ep == NULL) {
2849 if (errno == 0) {
2850 break;
2851 } else {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002852 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002853 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002854 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002855 Py_DECREF(d);
2856 return posix_error_with_allocated_filename(oname);
2857 }
2858 }
2859 if (ep->d_name[0] == '.' &&
2860 (NAMLEN(ep) == 1 ||
2861 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2862 continue;
Victor Stinnera45598a2010-05-14 16:35:39 +00002863 if (arg_is_unicode)
2864 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2865 else
2866 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00002867 if (v == NULL) {
Victor Stinnera45598a2010-05-14 16:35:39 +00002868 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002869 break;
2870 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002871 if (PyList_Append(d, v) != 0) {
2872 Py_DECREF(v);
Victor Stinnera45598a2010-05-14 16:35:39 +00002873 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002874 break;
2875 }
2876 Py_DECREF(v);
2877 }
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002878 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002879 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002880 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002881 Py_DECREF(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002882
Victor Stinner8c62be82010-05-06 00:08:46 +00002883 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002884
Tim Peters0bb44a42000-09-15 07:44:49 +00002885#endif /* which OS */
2886} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002887
Antoine Pitrou8250e232011-02-25 23:41:16 +00002888#ifdef HAVE_FDOPENDIR
Charles-François Natali77940902012-02-06 19:54:48 +01002889PyDoc_STRVAR(posix_flistdir__doc__,
2890"flistdir(fd) -> list_of_strings\n\n\
Charles-François Natali76961fa2012-01-10 20:25:09 +01002891Like listdir(), but uses a file descriptor instead.");
Antoine Pitrou8250e232011-02-25 23:41:16 +00002892
2893static PyObject *
Charles-François Natali77940902012-02-06 19:54:48 +01002894posix_flistdir(PyObject *self, PyObject *args)
Antoine Pitrou8250e232011-02-25 23:41:16 +00002895{
2896 PyObject *d, *v;
2897 DIR *dirp;
2898 struct dirent *ep;
2899 int fd;
2900
2901 errno = 0;
Charles-François Natali77940902012-02-06 19:54:48 +01002902 if (!PyArg_ParseTuple(args, "i:flistdir", &fd))
Antoine Pitrou8250e232011-02-25 23:41:16 +00002903 return NULL;
Charles-François Natali76961fa2012-01-10 20:25:09 +01002904 /* closedir() closes the FD, so we duplicate it */
2905 fd = dup(fd);
2906 if (fd < 0)
2907 return posix_error();
Antoine Pitrou8250e232011-02-25 23:41:16 +00002908 Py_BEGIN_ALLOW_THREADS
2909 dirp = fdopendir(fd);
2910 Py_END_ALLOW_THREADS
2911 if (dirp == NULL) {
2912 close(fd);
2913 return posix_error();
2914 }
2915 if ((d = PyList_New(0)) == NULL) {
2916 Py_BEGIN_ALLOW_THREADS
2917 closedir(dirp);
2918 Py_END_ALLOW_THREADS
2919 return NULL;
2920 }
2921 for (;;) {
2922 errno = 0;
2923 Py_BEGIN_ALLOW_THREADS
2924 ep = readdir(dirp);
2925 Py_END_ALLOW_THREADS
2926 if (ep == NULL) {
2927 if (errno == 0) {
2928 break;
2929 } else {
2930 Py_BEGIN_ALLOW_THREADS
Charles-François Natalif2840a82012-01-08 20:30:47 +01002931 rewinddir(dirp);
Antoine Pitrou8250e232011-02-25 23:41:16 +00002932 closedir(dirp);
2933 Py_END_ALLOW_THREADS
2934 Py_DECREF(d);
2935 return posix_error();
2936 }
2937 }
2938 if (ep->d_name[0] == '.' &&
2939 (NAMLEN(ep) == 1 ||
2940 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2941 continue;
2942 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2943 if (v == NULL) {
2944 Py_CLEAR(d);
2945 break;
2946 }
2947 if (PyList_Append(d, v) != 0) {
2948 Py_DECREF(v);
2949 Py_CLEAR(d);
2950 break;
2951 }
2952 Py_DECREF(v);
2953 }
2954 Py_BEGIN_ALLOW_THREADS
Charles-François Natalif2840a82012-01-08 20:30:47 +01002955 rewinddir(dirp);
Antoine Pitrou8250e232011-02-25 23:41:16 +00002956 closedir(dirp);
2957 Py_END_ALLOW_THREADS
2958
2959 return d;
2960}
2961#endif
2962
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002963#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002964/* A helper function for abspath on win32 */
2965static PyObject *
2966posix__getfullpathname(PyObject *self, PyObject *args)
2967{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002968 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002969 char outbuf[MAX_PATH*2];
2970 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002971 PyObject *po;
2972
2973 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
2974 {
2975 wchar_t *wpath;
2976 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2977 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00002978 DWORD result;
2979 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002980
2981 wpath = PyUnicode_AsUnicode(po);
2982 if (wpath == NULL)
2983 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002984 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02002985 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00002986 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02002987 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02002988 woutbufp = malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00002989 if (!woutbufp)
2990 return PyErr_NoMemory();
2991 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2992 }
2993 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01002994 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00002995 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02002996 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00002997 if (woutbufp != woutbuf)
2998 free(woutbufp);
2999 return v;
3000 }
3001 /* Drop the argument parsing error as narrow strings
3002 are also valid. */
3003 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003004
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003005 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3006 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003007 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003008 if (win32_warn_bytes_api())
3009 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003010 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003011 outbuf, &temp)) {
3012 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003013 return NULL;
3014 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003015 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3016 return PyUnicode_Decode(outbuf, strlen(outbuf),
3017 Py_FileSystemDefaultEncoding, NULL);
3018 }
3019 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003020} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003021
Brian Curtind25aef52011-06-13 15:16:04 -05003022
Brian Curtinf5e76d02010-11-24 13:14:05 +00003023
Brian Curtind40e6f72010-07-08 21:39:08 +00003024/* A helper function for samepath on windows */
3025static PyObject *
3026posix__getfinalpathname(PyObject *self, PyObject *args)
3027{
3028 HANDLE hFile;
3029 int buf_size;
3030 wchar_t *target_path;
3031 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003032 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003033 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003034
Victor Stinnereb5657a2011-09-30 01:44:27 +02003035 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003036 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003037 path = PyUnicode_AsUnicode(po);
3038 if (path == NULL)
3039 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003040
3041 if(!check_GetFinalPathNameByHandle()) {
3042 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3043 NotImplementedError. */
3044 return PyErr_Format(PyExc_NotImplementedError,
3045 "GetFinalPathNameByHandle not available on this platform");
3046 }
3047
3048 hFile = CreateFileW(
3049 path,
3050 0, /* desired access */
3051 0, /* share mode */
3052 NULL, /* security attributes */
3053 OPEN_EXISTING,
3054 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3055 FILE_FLAG_BACKUP_SEMANTICS,
3056 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003057
Victor Stinnereb5657a2011-09-30 01:44:27 +02003058 if(hFile == INVALID_HANDLE_VALUE)
3059 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003060
3061 /* We have a good handle to the target, use it to determine the
3062 target path name. */
3063 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3064
3065 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003066 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003067
3068 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
3069 if(!target_path)
3070 return PyErr_NoMemory();
3071
3072 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3073 buf_size, VOLUME_NAME_DOS);
3074 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003075 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003076
3077 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003078 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003079
3080 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003081 result = PyUnicode_FromWideChar(target_path, result_length);
Brian Curtind40e6f72010-07-08 21:39:08 +00003082 free(target_path);
3083 return result;
3084
3085} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003086
3087static PyObject *
3088posix__getfileinformation(PyObject *self, PyObject *args)
3089{
3090 HANDLE hFile;
3091 BY_HANDLE_FILE_INFORMATION info;
3092 int fd;
3093
3094 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
3095 return NULL;
3096
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003097 if (!_PyVerify_fd(fd))
3098 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003099
3100 hFile = (HANDLE)_get_osfhandle(fd);
3101 if (hFile == INVALID_HANDLE_VALUE)
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003102 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003103
3104 if (!GetFileInformationByHandle(hFile, &info))
3105 return win32_error("_getfileinformation", NULL);
3106
3107 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
3108 info.nFileIndexHigh,
3109 info.nFileIndexLow);
3110}
Brian Curtin9c669cc2011-06-08 18:17:18 -05003111
Brian Curtin95d028f2011-06-09 09:10:38 -05003112PyDoc_STRVAR(posix__isdir__doc__,
3113"Return true if the pathname refers to an existing directory.");
3114
Brian Curtin9c669cc2011-06-08 18:17:18 -05003115static PyObject *
3116posix__isdir(PyObject *self, PyObject *args)
3117{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003118 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003119 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003120 DWORD attributes;
3121
3122 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003123 wchar_t *wpath = PyUnicode_AsUnicode(po);
3124 if (wpath == NULL)
3125 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003126
3127 attributes = GetFileAttributesW(wpath);
3128 if (attributes == INVALID_FILE_ATTRIBUTES)
3129 Py_RETURN_FALSE;
3130 goto check;
3131 }
3132 /* Drop the argument parsing error as narrow strings
3133 are also valid. */
3134 PyErr_Clear();
3135
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003136 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003137 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003138 if (win32_warn_bytes_api())
3139 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003140 attributes = GetFileAttributesA(path);
3141 if (attributes == INVALID_FILE_ATTRIBUTES)
3142 Py_RETURN_FALSE;
3143
3144check:
3145 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3146 Py_RETURN_TRUE;
3147 else
3148 Py_RETURN_FALSE;
3149}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003150#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003151
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003152PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003153"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003154Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003155
Barry Warsaw53699e91996-12-10 23:23:01 +00003156static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003157posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003158{
Victor Stinner8c62be82010-05-06 00:08:46 +00003159 int res;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003160 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003161 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003162
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003163#ifdef MS_WINDOWS
Victor Stinnereb5657a2011-09-30 01:44:27 +02003164 PyObject *po;
3165 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode))
3166 {
3167 wchar_t *wpath = PyUnicode_AsUnicode(po);
3168 if (wpath == NULL)
3169 return NULL;
3170
Victor Stinner8c62be82010-05-06 00:08:46 +00003171 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02003172 res = CreateDirectoryW(wpath, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003173 Py_END_ALLOW_THREADS
3174 if (!res)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003175 return win32_error_object("mkdir", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003176 Py_INCREF(Py_None);
3177 return Py_None;
3178 }
3179 /* Drop the argument parsing error as narrow strings
3180 are also valid. */
3181 PyErr_Clear();
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003182 if (!PyArg_ParseTuple(args, "y|i:mkdir", &path, &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00003183 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003184 if (win32_warn_bytes_api())
3185 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003186 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003187 res = CreateDirectoryA(path, NULL);
3188 Py_END_ALLOW_THREADS
3189 if (!res) {
3190 win32_error("mkdir", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003191 return NULL;
3192 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003193 Py_INCREF(Py_None);
3194 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003195#else
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003196 PyObject *opath;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003197
Victor Stinner8c62be82010-05-06 00:08:46 +00003198 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
3199 PyUnicode_FSConverter, &opath, &mode))
3200 return NULL;
3201 path = PyBytes_AsString(opath);
3202 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00003203#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinner8c62be82010-05-06 00:08:46 +00003204 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003205#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003206 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003207#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003208 Py_END_ALLOW_THREADS
3209 if (res < 0)
3210 return posix_error_with_allocated_filename(opath);
3211 Py_DECREF(opath);
3212 Py_INCREF(Py_None);
3213 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003214#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003215}
3216
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003217
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003218/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3219#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003220#include <sys/resource.h>
3221#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003222
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003223
3224#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003225PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003226"nice(inc) -> new_priority\n\n\
3227Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003228
Barry Warsaw53699e91996-12-10 23:23:01 +00003229static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003230posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00003231{
Victor Stinner8c62be82010-05-06 00:08:46 +00003232 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00003233
Victor Stinner8c62be82010-05-06 00:08:46 +00003234 if (!PyArg_ParseTuple(args, "i:nice", &increment))
3235 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003236
Victor Stinner8c62be82010-05-06 00:08:46 +00003237 /* There are two flavours of 'nice': one that returns the new
3238 priority (as required by almost all standards out there) and the
3239 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3240 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003241
Victor Stinner8c62be82010-05-06 00:08:46 +00003242 If we are of the nice family that returns the new priority, we
3243 need to clear errno before the call, and check if errno is filled
3244 before calling posix_error() on a returnvalue of -1, because the
3245 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003246
Victor Stinner8c62be82010-05-06 00:08:46 +00003247 errno = 0;
3248 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003249#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003250 if (value == 0)
3251 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003252#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003253 if (value == -1 && errno != 0)
3254 /* either nice() or getpriority() returned an error */
3255 return posix_error();
3256 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003257}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003258#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003259
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003260
3261#ifdef HAVE_GETPRIORITY
3262PyDoc_STRVAR(posix_getpriority__doc__,
3263"getpriority(which, who) -> current_priority\n\n\
3264Get program scheduling priority.");
3265
3266static PyObject *
3267posix_getpriority(PyObject *self, PyObject *args)
3268{
3269 int which, who, retval;
3270
3271 if (!PyArg_ParseTuple(args, "ii", &which, &who))
3272 return NULL;
3273 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003274 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003275 if (errno != 0)
3276 return posix_error();
3277 return PyLong_FromLong((long)retval);
3278}
3279#endif /* HAVE_GETPRIORITY */
3280
3281
3282#ifdef HAVE_SETPRIORITY
3283PyDoc_STRVAR(posix_setpriority__doc__,
3284"setpriority(which, who, prio) -> None\n\n\
3285Set program scheduling priority.");
3286
3287static PyObject *
3288posix_setpriority(PyObject *self, PyObject *args)
3289{
3290 int which, who, prio, retval;
3291
3292 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
3293 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003294 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003295 if (retval == -1)
3296 return posix_error();
3297 Py_RETURN_NONE;
3298}
3299#endif /* HAVE_SETPRIORITY */
3300
3301
Barry Warsaw53699e91996-12-10 23:23:01 +00003302static PyObject *
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003303internal_rename(PyObject *self, PyObject *args, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003304{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003305#ifdef MS_WINDOWS
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003306 PyObject *src, *dst;
Victor Stinner8c62be82010-05-06 00:08:46 +00003307 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003308 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
3309 if (PyArg_ParseTuple(args,
3310 is_replace ? "UU:replace" : "UU:rename",
3311 &src, &dst))
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003312 {
3313 wchar_t *wsrc, *wdst;
3314
3315 wsrc = PyUnicode_AsUnicode(src);
3316 if (wsrc == NULL)
3317 return NULL;
3318 wdst = PyUnicode_AsUnicode(dst);
3319 if (wdst == NULL)
3320 return NULL;
3321 Py_BEGIN_ALLOW_THREADS
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003322 result = MoveFileExW(wsrc, wdst, flags);
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003323 Py_END_ALLOW_THREADS
3324 if (!result)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003325 return win32_error(is_replace ? "replace" : "rename", NULL);
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003326 Py_INCREF(Py_None);
3327 return Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003328 }
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003329 else {
3330 PyErr_Clear();
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003331 if (!PyArg_ParseTuple(args,
3332 is_replace ? "O&O&:replace" : "O&O&:rename",
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003333 PyUnicode_FSConverter, &src,
3334 PyUnicode_FSConverter, &dst))
3335 return NULL;
3336
3337 if (win32_warn_bytes_api())
3338 goto error;
3339
3340 Py_BEGIN_ALLOW_THREADS
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003341 result = MoveFileExA(PyBytes_AS_STRING(src),
3342 PyBytes_AS_STRING(dst), flags);
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003343 Py_END_ALLOW_THREADS
3344
3345 Py_XDECREF(src);
3346 Py_XDECREF(dst);
3347
3348 if (!result)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003349 return win32_error(is_replace ? "replace" : "rename", NULL);
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003350 Py_INCREF(Py_None);
3351 return Py_None;
3352
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003353error:
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003354 Py_XDECREF(src);
3355 Py_XDECREF(dst);
Victor Stinner8c62be82010-05-06 00:08:46 +00003356 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003357 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003358#else
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003359 return posix_2str(args,
3360 is_replace ? "O&O&:replace" : "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003361#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003362}
3363
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003364PyDoc_STRVAR(posix_rename__doc__,
3365"rename(old, new)\n\n\
3366Rename a file or directory.");
3367
3368static PyObject *
3369posix_rename(PyObject *self, PyObject *args)
3370{
3371 return internal_rename(self, args, 0);
3372}
3373
3374PyDoc_STRVAR(posix_replace__doc__,
3375"replace(old, new)\n\n\
3376Rename a file or directory, overwriting the destination.");
3377
3378static PyObject *
3379posix_replace(PyObject *self, PyObject *args)
3380{
3381 return internal_rename(self, args, 1);
3382}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003383
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003384PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003385"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003386Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003387
Barry Warsaw53699e91996-12-10 23:23:01 +00003388static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003389posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003390{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003391#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003392 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003393#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003394 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003395#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003396}
3397
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003398
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003399PyDoc_STRVAR(posix_stat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01003400"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003401Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003402
Barry Warsaw53699e91996-12-10 23:23:01 +00003403static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01003404posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003405{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003406#ifdef MS_WINDOWS
Victor Stinner4195b5c2012-02-08 23:03:19 +01003407 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_stat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003408#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01003409 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003410#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003411}
3412
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003413
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003414#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003415PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003416"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003417Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003418
Barry Warsaw53699e91996-12-10 23:23:01 +00003419static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003420posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003421{
Victor Stinner8c62be82010-05-06 00:08:46 +00003422 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00003423#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003424 wchar_t *command;
3425 if (!PyArg_ParseTuple(args, "u:system", &command))
3426 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003427
Victor Stinner8c62be82010-05-06 00:08:46 +00003428 Py_BEGIN_ALLOW_THREADS
3429 sts = _wsystem(command);
3430 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00003431#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003432 PyObject *command_obj;
3433 char *command;
3434 if (!PyArg_ParseTuple(args, "O&:system",
3435 PyUnicode_FSConverter, &command_obj))
3436 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003437
Victor Stinner8c62be82010-05-06 00:08:46 +00003438 command = PyBytes_AsString(command_obj);
3439 Py_BEGIN_ALLOW_THREADS
3440 sts = system(command);
3441 Py_END_ALLOW_THREADS
3442 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00003443#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003444 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003445}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003446#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003447
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003448
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003449PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003450"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003451Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003452
Barry Warsaw53699e91996-12-10 23:23:01 +00003453static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003454posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003455{
Victor Stinner8c62be82010-05-06 00:08:46 +00003456 int i;
3457 if (!PyArg_ParseTuple(args, "i:umask", &i))
3458 return NULL;
3459 i = (int)umask(i);
3460 if (i < 0)
3461 return posix_error();
3462 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003463}
3464
Brian Curtind40e6f72010-07-08 21:39:08 +00003465#ifdef MS_WINDOWS
3466
3467/* override the default DeleteFileW behavior so that directory
3468symlinks can be removed with this function, the same as with
3469Unix symlinks */
3470BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
3471{
3472 WIN32_FILE_ATTRIBUTE_DATA info;
3473 WIN32_FIND_DATAW find_data;
3474 HANDLE find_data_handle;
3475 int is_directory = 0;
3476 int is_link = 0;
3477
3478 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
3479 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003480
Brian Curtind40e6f72010-07-08 21:39:08 +00003481 /* Get WIN32_FIND_DATA structure for the path to determine if
3482 it is a symlink */
3483 if(is_directory &&
3484 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
3485 find_data_handle = FindFirstFileW(lpFileName, &find_data);
3486
3487 if(find_data_handle != INVALID_HANDLE_VALUE) {
3488 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
3489 FindClose(find_data_handle);
3490 }
3491 }
3492 }
3493
3494 if (is_directory && is_link)
3495 return RemoveDirectoryW(lpFileName);
3496
3497 return DeleteFileW(lpFileName);
3498}
3499#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003500
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003501PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003502"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003503Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003504
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003505PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003506"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003507Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003508
Barry Warsaw53699e91996-12-10 23:23:01 +00003509static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003510posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003511{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003512#ifdef MS_WINDOWS
Brian Curtin74e45612010-07-09 15:58:59 +00003513 return win32_1str(args, "remove", "y:remove", DeleteFileA,
3514 "U:remove", Py_DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003515#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003516 return posix_1str(args, "O&:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003517#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003518}
3519
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003520
Guido van Rossumb6775db1994-08-01 11:34:53 +00003521#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003522PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003523"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003524Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003525
Barry Warsaw53699e91996-12-10 23:23:01 +00003526static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003527posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003528{
Victor Stinner8c62be82010-05-06 00:08:46 +00003529 struct utsname u;
3530 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00003531
Victor Stinner8c62be82010-05-06 00:08:46 +00003532 Py_BEGIN_ALLOW_THREADS
3533 res = uname(&u);
3534 Py_END_ALLOW_THREADS
3535 if (res < 0)
3536 return posix_error();
3537 return Py_BuildValue("(sssss)",
3538 u.sysname,
3539 u.nodename,
3540 u.release,
3541 u.version,
3542 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003543}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003544#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003545
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003546
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003547PyDoc_STRVAR(posix_utime__doc__,
Brian Curtinc1b65d12011-11-07 14:18:54 -06003548"utime(path[, (atime, mtime)])\n\
3549Set the access and modified time of the file to the given values.\n\
3550If no second argument is used, set the access and modified times to\n\
3551the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003552
Barry Warsaw53699e91996-12-10 23:23:01 +00003553static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003554posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003555{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003556#ifdef MS_WINDOWS
Brian Curtinb0d5b5d2011-11-07 10:51:18 -06003557 PyObject *arg = Py_None;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003558 PyObject *obwpath;
Victor Stinner8c62be82010-05-06 00:08:46 +00003559 wchar_t *wpath = NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003560 const char *apath;
Victor Stinner8c62be82010-05-06 00:08:46 +00003561 HANDLE hFile;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003562 time_t atimesec, mtimesec;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003563 long ansec, mnsec;
Victor Stinner8c62be82010-05-06 00:08:46 +00003564 FILETIME atime, mtime;
3565 PyObject *result = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003566
Brian Curtin52fbea12011-11-06 13:41:17 -06003567 if (PyArg_ParseTuple(args, "U|O:utime", &obwpath, &arg)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003568 wpath = PyUnicode_AsUnicode(obwpath);
3569 if (wpath == NULL)
3570 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003571 Py_BEGIN_ALLOW_THREADS
3572 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
3573 NULL, OPEN_EXISTING,
3574 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3575 Py_END_ALLOW_THREADS
3576 if (hFile == INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003577 return win32_error_object("utime", obwpath);
3578 }
3579 else {
Victor Stinner8c62be82010-05-06 00:08:46 +00003580 /* Drop the argument parsing error as narrow strings
3581 are also valid. */
3582 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003583
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003584 if (!PyArg_ParseTuple(args, "y|O:utime", &apath, &arg))
3585 return NULL;
3586 if (win32_warn_bytes_api())
Victor Stinner8c62be82010-05-06 00:08:46 +00003587 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003588
Victor Stinner8c62be82010-05-06 00:08:46 +00003589 Py_BEGIN_ALLOW_THREADS
3590 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
3591 NULL, OPEN_EXISTING,
3592 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3593 Py_END_ALLOW_THREADS
3594 if (hFile == INVALID_HANDLE_VALUE) {
3595 win32_error("utime", apath);
Victor Stinner8c62be82010-05-06 00:08:46 +00003596 return NULL;
3597 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003598 }
3599
Brian Curtinb0d5b5d2011-11-07 10:51:18 -06003600 if (arg == Py_None) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003601 SYSTEMTIME now;
3602 GetSystemTime(&now);
3603 if (!SystemTimeToFileTime(&now, &mtime) ||
3604 !SystemTimeToFileTime(&now, &atime)) {
3605 win32_error("utime", NULL);
3606 goto done;
Stefan Krah0e803b32010-11-26 16:16:47 +00003607 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003608 }
3609 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3610 PyErr_SetString(PyExc_TypeError,
3611 "utime() arg 2 must be a tuple (atime, mtime)");
3612 goto done;
3613 }
3614 else {
Victor Stinner5d272cc2012-03-13 13:35:55 +01003615 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(arg, 0),
3616 &atimesec, &ansec) == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00003617 goto done;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003618 time_t_to_FILE_TIME(atimesec, ansec, &atime);
Victor Stinner5d272cc2012-03-13 13:35:55 +01003619 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(arg, 1),
3620 &mtimesec, &mnsec) == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00003621 goto done;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003622 time_t_to_FILE_TIME(mtimesec, mnsec, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00003623 }
3624 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3625 /* Avoid putting the file name into the error here,
3626 as that may confuse the user into believing that
3627 something is wrong with the file, when it also
3628 could be the time stamp that gives a problem. */
3629 win32_error("utime", NULL);
Antoine Pitroue85da7a2011-01-06 18:25:55 +00003630 goto done;
Victor Stinner8c62be82010-05-06 00:08:46 +00003631 }
3632 Py_INCREF(Py_None);
3633 result = Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003634done:
Victor Stinner8c62be82010-05-06 00:08:46 +00003635 CloseHandle(hFile);
3636 return result;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003637#else /* MS_WINDOWS */
Thomas Wouters477c8d52006-05-27 19:21:47 +00003638
Victor Stinner8c62be82010-05-06 00:08:46 +00003639 PyObject *opath;
3640 char *path;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003641 time_t atime, mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003642 long ansec, mnsec;
Victor Stinner8c62be82010-05-06 00:08:46 +00003643 int res;
Brian Curtinb0d5b5d2011-11-07 10:51:18 -06003644 PyObject* arg = Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003645
Brian Curtin52fbea12011-11-06 13:41:17 -06003646 if (!PyArg_ParseTuple(args, "O&|O:utime",
Victor Stinner8c62be82010-05-06 00:08:46 +00003647 PyUnicode_FSConverter, &opath, &arg))
3648 return NULL;
3649 path = PyBytes_AsString(opath);
Brian Curtinb0d5b5d2011-11-07 10:51:18 -06003650 if (arg == Py_None) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003651 /* optional time values not given */
3652 Py_BEGIN_ALLOW_THREADS
3653 res = utime(path, NULL);
3654 Py_END_ALLOW_THREADS
3655 }
3656 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3657 PyErr_SetString(PyExc_TypeError,
3658 "utime() arg 2 must be a tuple (atime, mtime)");
3659 Py_DECREF(opath);
3660 return NULL;
3661 }
3662 else {
Victor Stinner5d272cc2012-03-13 13:35:55 +01003663 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(arg, 0),
3664 &atime, &ansec) == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003665 Py_DECREF(opath);
3666 return NULL;
3667 }
Victor Stinner5d272cc2012-03-13 13:35:55 +01003668 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(arg, 1),
3669 &mtime, &mnsec) == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003670 Py_DECREF(opath);
3671 return NULL;
3672 }
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003673
3674 Py_BEGIN_ALLOW_THREADS
3675 {
3676#ifdef HAVE_UTIMENSAT
3677 struct timespec buf[2];
3678 buf[0].tv_sec = atime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003679 buf[0].tv_nsec = ansec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003680 buf[1].tv_sec = mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003681 buf[1].tv_nsec = mnsec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003682 res = utimensat(AT_FDCWD, path, buf, 0);
3683#elif defined(HAVE_UTIMES)
3684 struct timeval buf[2];
3685 buf[0].tv_sec = atime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003686 buf[0].tv_usec = ansec / 1000;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003687 buf[1].tv_sec = mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003688 buf[1].tv_usec = mnsec / 1000;
Victor Stinner8c62be82010-05-06 00:08:46 +00003689 res = utimes(path, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003690#elif defined(HAVE_UTIME_H)
3691 /* XXX should define struct utimbuf instead, above */
3692 struct utimbuf buf;
3693 buf.actime = atime;
3694 buf.modtime = mtime;
3695 res = utime(path, &buf);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003696#else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003697 time_t buf[2];
3698 buf[0] = atime;
3699 buf[1] = mtime;
3700 res = utime(path, buf);
3701#endif
3702 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003703 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003704 }
3705 if (res < 0) {
3706 return posix_error_with_allocated_filename(opath);
3707 }
3708 Py_DECREF(opath);
3709 Py_INCREF(Py_None);
3710 return Py_None;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003711#undef UTIME_EXTRACT
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003712#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003713}
3714
Ross Lagerwall7807c352011-03-17 20:20:30 +02003715#ifdef HAVE_FUTIMES
3716PyDoc_STRVAR(posix_futimes__doc__,
Brian Curtinc1b65d12011-11-07 14:18:54 -06003717"futimes(fd[, (atime, mtime)])\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003718Set the access and modified time of the file specified by the file\n\
Brian Curtinc1b65d12011-11-07 14:18:54 -06003719descriptor fd to the given values. If no second argument is used, set the\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003720access and modified times to the current time.");
3721
3722static PyObject *
3723posix_futimes(PyObject *self, PyObject *args)
3724{
3725 int res, fd;
Brian Curtinc1b65d12011-11-07 14:18:54 -06003726 PyObject* arg = Py_None;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003727 time_t atime, mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003728 long ansec, mnsec;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003729
Brian Curtinc1b65d12011-11-07 14:18:54 -06003730 if (!PyArg_ParseTuple(args, "i|O:futimes", &fd, &arg))
Ross Lagerwall7807c352011-03-17 20:20:30 +02003731 return NULL;
3732
3733 if (arg == Py_None) {
3734 /* optional time values not given */
3735 Py_BEGIN_ALLOW_THREADS
3736 res = futimes(fd, NULL);
3737 Py_END_ALLOW_THREADS
3738 }
3739 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3740 PyErr_SetString(PyExc_TypeError,
3741 "futimes() arg 2 must be a tuple (atime, mtime)");
3742 return NULL;
3743 }
3744 else {
Victor Stinner5d272cc2012-03-13 13:35:55 +01003745 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(arg, 0),
3746 &atime, &ansec) == -1) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003747 return NULL;
3748 }
Victor Stinner5d272cc2012-03-13 13:35:55 +01003749 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(arg, 1),
3750 &mtime, &mnsec) == -1) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003751 return NULL;
3752 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003753 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003754 {
3755#ifdef HAVE_FUTIMENS
3756 struct timespec buf[2];
3757 buf[0].tv_sec = atime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003758 buf[0].tv_nsec = ansec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003759 buf[1].tv_sec = mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003760 buf[1].tv_nsec = mnsec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003761 res = futimens(fd, buf);
3762#else
3763 struct timeval buf[2];
3764 buf[0].tv_sec = atime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003765 buf[0].tv_usec = ansec / 1000;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003766 buf[1].tv_sec = mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003767 buf[1].tv_usec = mnsec / 1000;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003768 res = futimes(fd, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003769#endif
3770 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003771 Py_END_ALLOW_THREADS
3772 }
3773 if (res < 0)
3774 return posix_error();
3775 Py_RETURN_NONE;
3776}
3777#endif
3778
3779#ifdef HAVE_LUTIMES
3780PyDoc_STRVAR(posix_lutimes__doc__,
Brian Curtinc1b65d12011-11-07 14:18:54 -06003781"lutimes(path[, (atime, mtime)])\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003782Like utime(), but if path is a symbolic link, it is not dereferenced.");
3783
3784static PyObject *
3785posix_lutimes(PyObject *self, PyObject *args)
3786{
Brian Curtinc1b65d12011-11-07 14:18:54 -06003787 PyObject *opath;
3788 PyObject *arg = Py_None;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003789 const char *path;
3790 int res;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003791 time_t atime, mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003792 long ansec, mnsec;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003793
Brian Curtinc1b65d12011-11-07 14:18:54 -06003794 if (!PyArg_ParseTuple(args, "O&|O:lutimes",
Ross Lagerwall7807c352011-03-17 20:20:30 +02003795 PyUnicode_FSConverter, &opath, &arg))
3796 return NULL;
3797 path = PyBytes_AsString(opath);
3798 if (arg == Py_None) {
3799 /* optional time values not given */
3800 Py_BEGIN_ALLOW_THREADS
3801 res = lutimes(path, NULL);
3802 Py_END_ALLOW_THREADS
3803 }
3804 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3805 PyErr_SetString(PyExc_TypeError,
3806 "lutimes() arg 2 must be a tuple (atime, mtime)");
3807 Py_DECREF(opath);
3808 return NULL;
3809 }
3810 else {
Victor Stinner5d272cc2012-03-13 13:35:55 +01003811 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(arg, 0),
3812 &atime, &ansec) == -1) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003813 Py_DECREF(opath);
3814 return NULL;
3815 }
Victor Stinner5d272cc2012-03-13 13:35:55 +01003816 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(arg, 1),
3817 &mtime, &mnsec) == -1) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003818 Py_DECREF(opath);
3819 return NULL;
3820 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003821 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003822 {
3823#ifdef HAVE_UTIMENSAT
3824 struct timespec buf[2];
3825 buf[0].tv_sec = atime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003826 buf[0].tv_nsec = ansec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003827 buf[1].tv_sec = mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003828 buf[1].tv_nsec = mnsec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003829 res = utimensat(AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW);
3830#else
3831 struct timeval buf[2];
3832 buf[0].tv_sec = atime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003833 buf[0].tv_usec = ansec / 1000;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003834 buf[1].tv_sec = mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003835 buf[1].tv_usec = mnsec / 1000;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003836 res = lutimes(path, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003837#endif
3838 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003839 Py_END_ALLOW_THREADS
3840 }
3841 Py_DECREF(opath);
3842 if (res < 0)
3843 return posix_error();
3844 Py_RETURN_NONE;
3845}
3846#endif
3847
3848#ifdef HAVE_FUTIMENS
3849PyDoc_STRVAR(posix_futimens__doc__,
Brian Curtinc1b65d12011-11-07 14:18:54 -06003850"futimens(fd[, (atime_sec, atime_nsec), (mtime_sec, mtime_nsec)])\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003851Updates the timestamps of a file specified by the file descriptor fd, with\n\
3852nanosecond precision.\n\
Brian Curtinc1b65d12011-11-07 14:18:54 -06003853If no second argument is given, set atime and mtime to the current time.\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003854If *_nsec is specified as UTIME_NOW, the timestamp is updated to the\n\
3855current time.\n\
3856If *_nsec is specified as UTIME_OMIT, the timestamp is not updated.");
3857
3858static PyObject *
3859posix_futimens(PyObject *self, PyObject *args)
3860{
3861 int res, fd;
Brian Curtinc1b65d12011-11-07 14:18:54 -06003862 PyObject *atime = Py_None;
3863 PyObject *mtime = Py_None;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003864 struct timespec buf[2];
3865
Brian Curtinc1b65d12011-11-07 14:18:54 -06003866 if (!PyArg_ParseTuple(args, "i|OO:futimens",
Ross Lagerwall7807c352011-03-17 20:20:30 +02003867 &fd, &atime, &mtime))
3868 return NULL;
3869 if (atime == Py_None && mtime == Py_None) {
3870 /* optional time values not given */
3871 Py_BEGIN_ALLOW_THREADS
3872 res = futimens(fd, NULL);
3873 Py_END_ALLOW_THREADS
3874 }
3875 else if (!PyTuple_Check(atime) || PyTuple_Size(atime) != 2) {
3876 PyErr_SetString(PyExc_TypeError,
3877 "futimens() arg 2 must be a tuple (atime_sec, atime_nsec)");
3878 return NULL;
3879 }
3880 else if (!PyTuple_Check(mtime) || PyTuple_Size(mtime) != 2) {
3881 PyErr_SetString(PyExc_TypeError,
3882 "futimens() arg 3 must be a tuple (mtime_sec, mtime_nsec)");
3883 return NULL;
3884 }
3885 else {
3886 if (!PyArg_ParseTuple(atime, "ll:futimens",
3887 &(buf[0].tv_sec), &(buf[0].tv_nsec))) {
3888 return NULL;
3889 }
3890 if (!PyArg_ParseTuple(mtime, "ll:futimens",
3891 &(buf[1].tv_sec), &(buf[1].tv_nsec))) {
3892 return NULL;
3893 }
3894 Py_BEGIN_ALLOW_THREADS
3895 res = futimens(fd, buf);
3896 Py_END_ALLOW_THREADS
3897 }
3898 if (res < 0)
3899 return posix_error();
3900 Py_RETURN_NONE;
3901}
3902#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003903
Guido van Rossum3b066191991-06-04 19:40:25 +00003904/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003905
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003906PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003907"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003908Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003909
Barry Warsaw53699e91996-12-10 23:23:01 +00003910static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003911posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003912{
Victor Stinner8c62be82010-05-06 00:08:46 +00003913 int sts;
3914 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3915 return NULL;
3916 _exit(sts);
3917 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003918}
3919
Martin v. Löwis114619e2002-10-07 06:44:21 +00003920#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3921static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003922free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003923{
Victor Stinner8c62be82010-05-06 00:08:46 +00003924 Py_ssize_t i;
3925 for (i = 0; i < count; i++)
3926 PyMem_Free(array[i]);
3927 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003928}
Martin v. Löwis011e8422009-05-05 04:43:17 +00003929
Antoine Pitrou69f71142009-05-24 21:25:49 +00003930static
Martin v. Löwis011e8422009-05-05 04:43:17 +00003931int fsconvert_strdup(PyObject *o, char**out)
3932{
Victor Stinner8c62be82010-05-06 00:08:46 +00003933 PyObject *bytes;
3934 Py_ssize_t size;
3935 if (!PyUnicode_FSConverter(o, &bytes))
3936 return 0;
3937 size = PyBytes_GET_SIZE(bytes);
3938 *out = PyMem_Malloc(size+1);
3939 if (!*out)
3940 return 0;
3941 memcpy(*out, PyBytes_AsString(bytes), size+1);
3942 Py_DECREF(bytes);
3943 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003944}
Martin v. Löwis114619e2002-10-07 06:44:21 +00003945#endif
3946
Ross Lagerwall7807c352011-03-17 20:20:30 +02003947#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00003948static char**
3949parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
3950{
Victor Stinner8c62be82010-05-06 00:08:46 +00003951 char **envlist;
3952 Py_ssize_t i, pos, envc;
3953 PyObject *keys=NULL, *vals=NULL;
3954 PyObject *key, *val, *key2, *val2;
3955 char *p, *k, *v;
3956 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003957
Victor Stinner8c62be82010-05-06 00:08:46 +00003958 i = PyMapping_Size(env);
3959 if (i < 0)
3960 return NULL;
3961 envlist = PyMem_NEW(char *, i + 1);
3962 if (envlist == NULL) {
3963 PyErr_NoMemory();
3964 return NULL;
3965 }
3966 envc = 0;
3967 keys = PyMapping_Keys(env);
3968 vals = PyMapping_Values(env);
3969 if (!keys || !vals)
3970 goto error;
3971 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3972 PyErr_Format(PyExc_TypeError,
3973 "env.keys() or env.values() is not a list");
3974 goto error;
3975 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003976
Victor Stinner8c62be82010-05-06 00:08:46 +00003977 for (pos = 0; pos < i; pos++) {
3978 key = PyList_GetItem(keys, pos);
3979 val = PyList_GetItem(vals, pos);
3980 if (!key || !val)
3981 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003982
Victor Stinner8c62be82010-05-06 00:08:46 +00003983 if (PyUnicode_FSConverter(key, &key2) == 0)
3984 goto error;
3985 if (PyUnicode_FSConverter(val, &val2) == 0) {
3986 Py_DECREF(key2);
3987 goto error;
3988 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003989
3990#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003991 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3992 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00003993#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003994 k = PyBytes_AsString(key2);
3995 v = PyBytes_AsString(val2);
3996 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003997
Victor Stinner8c62be82010-05-06 00:08:46 +00003998 p = PyMem_NEW(char, len);
3999 if (p == NULL) {
4000 PyErr_NoMemory();
4001 Py_DECREF(key2);
4002 Py_DECREF(val2);
4003 goto error;
4004 }
4005 PyOS_snprintf(p, len, "%s=%s", k, v);
4006 envlist[envc++] = p;
4007 Py_DECREF(key2);
4008 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004009#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004010 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004011#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004012 }
4013 Py_DECREF(vals);
4014 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004015
Victor Stinner8c62be82010-05-06 00:08:46 +00004016 envlist[envc] = 0;
4017 *envc_ptr = envc;
4018 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004019
4020error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004021 Py_XDECREF(keys);
4022 Py_XDECREF(vals);
4023 while (--envc >= 0)
4024 PyMem_DEL(envlist[envc]);
4025 PyMem_DEL(envlist);
4026 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004027}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004028
Ross Lagerwall7807c352011-03-17 20:20:30 +02004029static char**
4030parse_arglist(PyObject* argv, Py_ssize_t *argc)
4031{
4032 int i;
4033 char **argvlist = PyMem_NEW(char *, *argc+1);
4034 if (argvlist == NULL) {
4035 PyErr_NoMemory();
4036 return NULL;
4037 }
4038 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004039 PyObject* item = PySequence_ITEM(argv, i);
4040 if (item == NULL)
4041 goto fail;
4042 if (!fsconvert_strdup(item, &argvlist[i])) {
4043 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004044 goto fail;
4045 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004046 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004047 }
4048 argvlist[*argc] = NULL;
4049 return argvlist;
4050fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004051 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004052 free_string_array(argvlist, *argc);
4053 return NULL;
4054}
4055#endif
4056
4057#ifdef HAVE_EXECV
4058PyDoc_STRVAR(posix_execv__doc__,
4059"execv(path, args)\n\n\
4060Execute an executable path with arguments, replacing current process.\n\
4061\n\
4062 path: path of executable file\n\
4063 args: tuple or list of strings");
4064
4065static PyObject *
4066posix_execv(PyObject *self, PyObject *args)
4067{
4068 PyObject *opath;
4069 char *path;
4070 PyObject *argv;
4071 char **argvlist;
4072 Py_ssize_t argc;
4073
4074 /* execv has two arguments: (path, argv), where
4075 argv is a list or tuple of strings. */
4076
4077 if (!PyArg_ParseTuple(args, "O&O:execv",
4078 PyUnicode_FSConverter,
4079 &opath, &argv))
4080 return NULL;
4081 path = PyBytes_AsString(opath);
4082 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4083 PyErr_SetString(PyExc_TypeError,
4084 "execv() arg 2 must be a tuple or list");
4085 Py_DECREF(opath);
4086 return NULL;
4087 }
4088 argc = PySequence_Size(argv);
4089 if (argc < 1) {
4090 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
4091 Py_DECREF(opath);
4092 return NULL;
4093 }
4094
4095 argvlist = parse_arglist(argv, &argc);
4096 if (argvlist == NULL) {
4097 Py_DECREF(opath);
4098 return NULL;
4099 }
4100
4101 execv(path, argvlist);
4102
4103 /* If we get here it's definitely an error */
4104
4105 free_string_array(argvlist, argc);
4106 Py_DECREF(opath);
4107 return posix_error();
4108}
4109
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004110PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004111"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004112Execute a path with arguments and environment, replacing current process.\n\
4113\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004114 path: path of executable file\n\
4115 args: tuple or list of arguments\n\
4116 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004117
Barry Warsaw53699e91996-12-10 23:23:01 +00004118static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004119posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004120{
Victor Stinner8c62be82010-05-06 00:08:46 +00004121 PyObject *opath;
4122 char *path;
4123 PyObject *argv, *env;
4124 char **argvlist;
4125 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004126 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004127
Victor Stinner8c62be82010-05-06 00:08:46 +00004128 /* execve has three arguments: (path, argv, env), where
4129 argv is a list or tuple of strings and env is a dictionary
4130 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004131
Victor Stinner8c62be82010-05-06 00:08:46 +00004132 if (!PyArg_ParseTuple(args, "O&OO:execve",
4133 PyUnicode_FSConverter,
4134 &opath, &argv, &env))
4135 return NULL;
4136 path = PyBytes_AsString(opath);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004137 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004138 PyErr_SetString(PyExc_TypeError,
4139 "execve() arg 2 must be a tuple or list");
4140 goto fail_0;
4141 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004142 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00004143 if (!PyMapping_Check(env)) {
4144 PyErr_SetString(PyExc_TypeError,
4145 "execve() arg 3 must be a mapping object");
4146 goto fail_0;
4147 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004148
Ross Lagerwall7807c352011-03-17 20:20:30 +02004149 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004150 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004151 goto fail_0;
4152 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004153
Victor Stinner8c62be82010-05-06 00:08:46 +00004154 envlist = parse_envlist(env, &envc);
4155 if (envlist == NULL)
4156 goto fail_1;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004157
Victor Stinner8c62be82010-05-06 00:08:46 +00004158 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00004159
Victor Stinner8c62be82010-05-06 00:08:46 +00004160 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004161
Victor Stinner8c62be82010-05-06 00:08:46 +00004162 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004163
Victor Stinner8c62be82010-05-06 00:08:46 +00004164 while (--envc >= 0)
4165 PyMem_DEL(envlist[envc]);
4166 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004167 fail_1:
Ross Lagerwall7807c352011-03-17 20:20:30 +02004168 free_string_array(argvlist, argc);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004169 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004170 Py_DECREF(opath);
4171 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004172}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004173#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004174
Ross Lagerwall7807c352011-03-17 20:20:30 +02004175#ifdef HAVE_FEXECVE
4176PyDoc_STRVAR(posix_fexecve__doc__,
4177"fexecve(fd, args, env)\n\n\
4178Execute the program specified by a file descriptor with arguments and\n\
4179environment, replacing the current process.\n\
4180\n\
4181 fd: file descriptor of executable\n\
4182 args: tuple or list of arguments\n\
4183 env: dictionary of strings mapping to strings");
4184
4185static PyObject *
4186posix_fexecve(PyObject *self, PyObject *args)
4187{
4188 int fd;
4189 PyObject *argv, *env;
4190 char **argvlist;
4191 char **envlist;
4192 Py_ssize_t argc, envc;
4193
4194 if (!PyArg_ParseTuple(args, "iOO:fexecve",
4195 &fd, &argv, &env))
4196 return NULL;
4197 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4198 PyErr_SetString(PyExc_TypeError,
4199 "fexecve() arg 2 must be a tuple or list");
4200 return NULL;
4201 }
4202 argc = PySequence_Size(argv);
4203 if (!PyMapping_Check(env)) {
4204 PyErr_SetString(PyExc_TypeError,
4205 "fexecve() arg 3 must be a mapping object");
4206 return NULL;
4207 }
4208
4209 argvlist = parse_arglist(argv, &argc);
4210 if (argvlist == NULL)
4211 return NULL;
4212
4213 envlist = parse_envlist(env, &envc);
4214 if (envlist == NULL)
4215 goto fail;
4216
4217 fexecve(fd, argvlist, envlist);
4218
4219 /* If we get here it's definitely an error */
4220
4221 (void) posix_error();
4222
4223 while (--envc >= 0)
4224 PyMem_DEL(envlist[envc]);
4225 PyMem_DEL(envlist);
4226 fail:
4227 free_string_array(argvlist, argc);
4228 return NULL;
4229}
4230#endif /* HAVE_FEXECVE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004231
Guido van Rossuma1065681999-01-25 23:20:23 +00004232#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004233PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004234"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004235Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004236\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004237 mode: mode of process creation\n\
4238 path: path of executable file\n\
4239 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004240
4241static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004242posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004243{
Victor Stinner8c62be82010-05-06 00:08:46 +00004244 PyObject *opath;
4245 char *path;
4246 PyObject *argv;
4247 char **argvlist;
4248 int mode, i;
4249 Py_ssize_t argc;
4250 Py_intptr_t spawnval;
4251 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00004252
Victor Stinner8c62be82010-05-06 00:08:46 +00004253 /* spawnv has three arguments: (mode, path, argv), where
4254 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004255
Victor Stinner8c62be82010-05-06 00:08:46 +00004256 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
4257 PyUnicode_FSConverter,
4258 &opath, &argv))
4259 return NULL;
4260 path = PyBytes_AsString(opath);
4261 if (PyList_Check(argv)) {
4262 argc = PyList_Size(argv);
4263 getitem = PyList_GetItem;
4264 }
4265 else if (PyTuple_Check(argv)) {
4266 argc = PyTuple_Size(argv);
4267 getitem = PyTuple_GetItem;
4268 }
4269 else {
4270 PyErr_SetString(PyExc_TypeError,
4271 "spawnv() arg 2 must be a tuple or list");
4272 Py_DECREF(opath);
4273 return NULL;
4274 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004275
Victor Stinner8c62be82010-05-06 00:08:46 +00004276 argvlist = PyMem_NEW(char *, argc+1);
4277 if (argvlist == NULL) {
4278 Py_DECREF(opath);
4279 return PyErr_NoMemory();
4280 }
4281 for (i = 0; i < argc; i++) {
4282 if (!fsconvert_strdup((*getitem)(argv, i),
4283 &argvlist[i])) {
4284 free_string_array(argvlist, i);
4285 PyErr_SetString(
4286 PyExc_TypeError,
4287 "spawnv() arg 2 must contain only strings");
4288 Py_DECREF(opath);
4289 return NULL;
4290 }
4291 }
4292 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004293
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004294#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004295 Py_BEGIN_ALLOW_THREADS
4296 spawnval = spawnv(mode, path, argvlist);
4297 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004298#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004299 if (mode == _OLD_P_OVERLAY)
4300 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00004301
Victor Stinner8c62be82010-05-06 00:08:46 +00004302 Py_BEGIN_ALLOW_THREADS
4303 spawnval = _spawnv(mode, path, argvlist);
4304 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004305#endif
Tim Peters5aa91602002-01-30 05:46:57 +00004306
Victor Stinner8c62be82010-05-06 00:08:46 +00004307 free_string_array(argvlist, argc);
4308 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00004309
Victor Stinner8c62be82010-05-06 00:08:46 +00004310 if (spawnval == -1)
4311 return posix_error();
4312 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004313#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00004314 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004315#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004316 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004317#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00004318}
4319
4320
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004321PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004322"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004323Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004324\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004325 mode: mode of process creation\n\
4326 path: path of executable file\n\
4327 args: tuple or list of arguments\n\
4328 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004329
4330static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004331posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004332{
Victor Stinner8c62be82010-05-06 00:08:46 +00004333 PyObject *opath;
4334 char *path;
4335 PyObject *argv, *env;
4336 char **argvlist;
4337 char **envlist;
4338 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00004339 int mode;
4340 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00004341 Py_intptr_t spawnval;
4342 PyObject *(*getitem)(PyObject *, Py_ssize_t);
4343 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00004344
Victor Stinner8c62be82010-05-06 00:08:46 +00004345 /* spawnve has four arguments: (mode, path, argv, env), where
4346 argv is a list or tuple of strings and env is a dictionary
4347 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004348
Victor Stinner8c62be82010-05-06 00:08:46 +00004349 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
4350 PyUnicode_FSConverter,
4351 &opath, &argv, &env))
4352 return NULL;
4353 path = PyBytes_AsString(opath);
4354 if (PyList_Check(argv)) {
4355 argc = PyList_Size(argv);
4356 getitem = PyList_GetItem;
4357 }
4358 else if (PyTuple_Check(argv)) {
4359 argc = PyTuple_Size(argv);
4360 getitem = PyTuple_GetItem;
4361 }
4362 else {
4363 PyErr_SetString(PyExc_TypeError,
4364 "spawnve() arg 2 must be a tuple or list");
4365 goto fail_0;
4366 }
4367 if (!PyMapping_Check(env)) {
4368 PyErr_SetString(PyExc_TypeError,
4369 "spawnve() arg 3 must be a mapping object");
4370 goto fail_0;
4371 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004372
Victor Stinner8c62be82010-05-06 00:08:46 +00004373 argvlist = PyMem_NEW(char *, argc+1);
4374 if (argvlist == NULL) {
4375 PyErr_NoMemory();
4376 goto fail_0;
4377 }
4378 for (i = 0; i < argc; i++) {
4379 if (!fsconvert_strdup((*getitem)(argv, i),
4380 &argvlist[i]))
4381 {
4382 lastarg = i;
4383 goto fail_1;
4384 }
4385 }
4386 lastarg = argc;
4387 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004388
Victor Stinner8c62be82010-05-06 00:08:46 +00004389 envlist = parse_envlist(env, &envc);
4390 if (envlist == NULL)
4391 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00004392
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004393#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004394 Py_BEGIN_ALLOW_THREADS
4395 spawnval = spawnve(mode, path, argvlist, envlist);
4396 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004397#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004398 if (mode == _OLD_P_OVERLAY)
4399 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00004400
Victor Stinner8c62be82010-05-06 00:08:46 +00004401 Py_BEGIN_ALLOW_THREADS
4402 spawnval = _spawnve(mode, path, argvlist, envlist);
4403 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004404#endif
Tim Peters25059d32001-12-07 20:35:43 +00004405
Victor Stinner8c62be82010-05-06 00:08:46 +00004406 if (spawnval == -1)
4407 (void) posix_error();
4408 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004409#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00004410 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004411#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004412 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004413#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00004414
Victor Stinner8c62be82010-05-06 00:08:46 +00004415 while (--envc >= 0)
4416 PyMem_DEL(envlist[envc]);
4417 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004418 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00004419 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004420 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004421 Py_DECREF(opath);
4422 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00004423}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004424
4425/* OS/2 supports spawnvp & spawnvpe natively */
4426#if defined(PYOS_OS2)
4427PyDoc_STRVAR(posix_spawnvp__doc__,
4428"spawnvp(mode, file, args)\n\n\
4429Execute the program 'file' in a new process, using the environment\n\
4430search path to find the file.\n\
4431\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004432 mode: mode of process creation\n\
4433 file: executable file name\n\
4434 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004435
4436static PyObject *
4437posix_spawnvp(PyObject *self, PyObject *args)
4438{
Victor Stinner8c62be82010-05-06 00:08:46 +00004439 PyObject *opath;
4440 char *path;
4441 PyObject *argv;
4442 char **argvlist;
4443 int mode, i, argc;
4444 Py_intptr_t spawnval;
4445 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004446
Victor Stinner8c62be82010-05-06 00:08:46 +00004447 /* spawnvp has three arguments: (mode, path, argv), where
4448 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004449
Victor Stinner8c62be82010-05-06 00:08:46 +00004450 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
4451 PyUnicode_FSConverter,
4452 &opath, &argv))
4453 return NULL;
4454 path = PyBytes_AsString(opath);
4455 if (PyList_Check(argv)) {
4456 argc = PyList_Size(argv);
4457 getitem = PyList_GetItem;
4458 }
4459 else if (PyTuple_Check(argv)) {
4460 argc = PyTuple_Size(argv);
4461 getitem = PyTuple_GetItem;
4462 }
4463 else {
4464 PyErr_SetString(PyExc_TypeError,
4465 "spawnvp() arg 2 must be a tuple or list");
4466 Py_DECREF(opath);
4467 return NULL;
4468 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004469
Victor Stinner8c62be82010-05-06 00:08:46 +00004470 argvlist = PyMem_NEW(char *, argc+1);
4471 if (argvlist == NULL) {
4472 Py_DECREF(opath);
4473 return PyErr_NoMemory();
4474 }
4475 for (i = 0; i < argc; i++) {
4476 if (!fsconvert_strdup((*getitem)(argv, i),
4477 &argvlist[i])) {
4478 free_string_array(argvlist, i);
4479 PyErr_SetString(
4480 PyExc_TypeError,
4481 "spawnvp() arg 2 must contain only strings");
4482 Py_DECREF(opath);
4483 return NULL;
4484 }
4485 }
4486 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004487
Victor Stinner8c62be82010-05-06 00:08:46 +00004488 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004489#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004490 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004491#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004492 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004493#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004494 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004495
Victor Stinner8c62be82010-05-06 00:08:46 +00004496 free_string_array(argvlist, argc);
4497 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004498
Victor Stinner8c62be82010-05-06 00:08:46 +00004499 if (spawnval == -1)
4500 return posix_error();
4501 else
4502 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004503}
4504
4505
4506PyDoc_STRVAR(posix_spawnvpe__doc__,
4507"spawnvpe(mode, file, args, env)\n\n\
4508Execute the program 'file' in a new process, using the environment\n\
4509search path to find the file.\n\
4510\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004511 mode: mode of process creation\n\
4512 file: executable file name\n\
4513 args: tuple or list of arguments\n\
4514 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004515
4516static PyObject *
4517posix_spawnvpe(PyObject *self, PyObject *args)
4518{
Ross Lagerwalldcfde5a2011-11-04 07:09:14 +02004519 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00004520 char *path;
4521 PyObject *argv, *env;
4522 char **argvlist;
4523 char **envlist;
4524 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00004525 int mode;
4526 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00004527 Py_intptr_t spawnval;
4528 PyObject *(*getitem)(PyObject *, Py_ssize_t);
4529 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004530
Victor Stinner8c62be82010-05-06 00:08:46 +00004531 /* spawnvpe has four arguments: (mode, path, argv, env), where
4532 argv is a list or tuple of strings and env is a dictionary
4533 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004534
Victor Stinner8c62be82010-05-06 00:08:46 +00004535 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
4536 PyUnicode_FSConverter,
4537 &opath, &argv, &env))
4538 return NULL;
4539 path = PyBytes_AsString(opath);
4540 if (PyList_Check(argv)) {
4541 argc = PyList_Size(argv);
4542 getitem = PyList_GetItem;
4543 }
4544 else if (PyTuple_Check(argv)) {
4545 argc = PyTuple_Size(argv);
4546 getitem = PyTuple_GetItem;
4547 }
4548 else {
4549 PyErr_SetString(PyExc_TypeError,
4550 "spawnvpe() arg 2 must be a tuple or list");
4551 goto fail_0;
4552 }
4553 if (!PyMapping_Check(env)) {
4554 PyErr_SetString(PyExc_TypeError,
4555 "spawnvpe() arg 3 must be a mapping object");
4556 goto fail_0;
4557 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004558
Victor Stinner8c62be82010-05-06 00:08:46 +00004559 argvlist = PyMem_NEW(char *, argc+1);
4560 if (argvlist == NULL) {
4561 PyErr_NoMemory();
4562 goto fail_0;
4563 }
4564 for (i = 0; i < argc; i++) {
4565 if (!fsconvert_strdup((*getitem)(argv, i),
4566 &argvlist[i]))
4567 {
4568 lastarg = i;
4569 goto fail_1;
4570 }
4571 }
4572 lastarg = argc;
4573 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004574
Victor Stinner8c62be82010-05-06 00:08:46 +00004575 envlist = parse_envlist(env, &envc);
4576 if (envlist == NULL)
4577 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004578
Victor Stinner8c62be82010-05-06 00:08:46 +00004579 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004580#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004581 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004582#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004583 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004584#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004585 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004586
Victor Stinner8c62be82010-05-06 00:08:46 +00004587 if (spawnval == -1)
4588 (void) posix_error();
4589 else
4590 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004591
Victor Stinner8c62be82010-05-06 00:08:46 +00004592 while (--envc >= 0)
4593 PyMem_DEL(envlist[envc]);
4594 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004595 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00004596 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004597 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004598 Py_DECREF(opath);
4599 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004600}
4601#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00004602#endif /* HAVE_SPAWNV */
4603
4604
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004605#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004606PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004607"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004608Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
4609\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004610Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004611
4612static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004613posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004614{
Victor Stinner8c62be82010-05-06 00:08:46 +00004615 pid_t pid;
4616 int result = 0;
4617 _PyImport_AcquireLock();
4618 pid = fork1();
4619 if (pid == 0) {
4620 /* child: this clobbers and resets the import lock. */
4621 PyOS_AfterFork();
4622 } else {
4623 /* parent: release the import lock. */
4624 result = _PyImport_ReleaseLock();
4625 }
4626 if (pid == -1)
4627 return posix_error();
4628 if (result < 0) {
4629 /* Don't clobber the OSError if the fork failed. */
4630 PyErr_SetString(PyExc_RuntimeError,
4631 "not holding the import lock");
4632 return NULL;
4633 }
4634 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004635}
4636#endif
4637
4638
Guido van Rossumad0ee831995-03-01 10:34:45 +00004639#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004640PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004641"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004642Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004643Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004644
Barry Warsaw53699e91996-12-10 23:23:01 +00004645static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004646posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004647{
Victor Stinner8c62be82010-05-06 00:08:46 +00004648 pid_t pid;
4649 int result = 0;
4650 _PyImport_AcquireLock();
4651 pid = fork();
4652 if (pid == 0) {
4653 /* child: this clobbers and resets the import lock. */
4654 PyOS_AfterFork();
4655 } else {
4656 /* parent: release the import lock. */
4657 result = _PyImport_ReleaseLock();
4658 }
4659 if (pid == -1)
4660 return posix_error();
4661 if (result < 0) {
4662 /* Don't clobber the OSError if the fork failed. */
4663 PyErr_SetString(PyExc_RuntimeError,
4664 "not holding the import lock");
4665 return NULL;
4666 }
4667 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00004668}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004669#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004670
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004671#ifdef HAVE_SCHED_H
4672
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02004673#ifdef HAVE_SCHED_GET_PRIORITY_MAX
4674
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004675PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
4676"sched_get_priority_max(policy)\n\n\
4677Get the maximum scheduling priority for *policy*.");
4678
4679static PyObject *
4680posix_sched_get_priority_max(PyObject *self, PyObject *args)
4681{
4682 int policy, max;
4683
4684 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
4685 return NULL;
4686 max = sched_get_priority_max(policy);
4687 if (max < 0)
4688 return posix_error();
4689 return PyLong_FromLong(max);
4690}
4691
4692PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
4693"sched_get_priority_min(policy)\n\n\
4694Get the minimum scheduling priority for *policy*.");
4695
4696static PyObject *
4697posix_sched_get_priority_min(PyObject *self, PyObject *args)
4698{
4699 int policy, min;
4700
4701 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
4702 return NULL;
4703 min = sched_get_priority_min(policy);
4704 if (min < 0)
4705 return posix_error();
4706 return PyLong_FromLong(min);
4707}
4708
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02004709#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
4710
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004711#ifdef HAVE_SCHED_SETSCHEDULER
4712
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004713PyDoc_STRVAR(posix_sched_getscheduler__doc__,
4714"sched_getscheduler(pid)\n\n\
4715Get the scheduling policy for the process with a PID of *pid*.\n\
4716Passing a PID of 0 returns the scheduling policy for the calling process.");
4717
4718static PyObject *
4719posix_sched_getscheduler(PyObject *self, PyObject *args)
4720{
4721 pid_t pid;
4722 int policy;
4723
4724 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
4725 return NULL;
4726 policy = sched_getscheduler(pid);
4727 if (policy < 0)
4728 return posix_error();
4729 return PyLong_FromLong(policy);
4730}
4731
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004732#endif
4733
4734#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
4735
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004736static PyObject *
4737sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
4738{
4739 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05004740 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004741
4742 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
4743 return NULL;
4744 res = PyStructSequence_New(type);
4745 if (!res)
4746 return NULL;
4747 Py_INCREF(priority);
4748 PyStructSequence_SET_ITEM(res, 0, priority);
4749 return res;
4750}
4751
4752PyDoc_STRVAR(sched_param__doc__,
4753"sched_param(sched_priority): A scheduling parameter.\n\n\
4754Current has only one field: sched_priority");
4755
4756static PyStructSequence_Field sched_param_fields[] = {
4757 {"sched_priority", "the scheduling priority"},
4758 {0}
4759};
4760
4761static PyStructSequence_Desc sched_param_desc = {
4762 "sched_param", /* name */
4763 sched_param__doc__, /* doc */
4764 sched_param_fields,
4765 1
4766};
4767
4768static int
4769convert_sched_param(PyObject *param, struct sched_param *res)
4770{
4771 long priority;
4772
4773 if (Py_TYPE(param) != &SchedParamType) {
4774 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
4775 return 0;
4776 }
4777 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
4778 if (priority == -1 && PyErr_Occurred())
4779 return 0;
4780 if (priority > INT_MAX || priority < INT_MIN) {
4781 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
4782 return 0;
4783 }
4784 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
4785 return 1;
4786}
4787
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004788#endif
4789
4790#ifdef HAVE_SCHED_SETSCHEDULER
4791
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004792PyDoc_STRVAR(posix_sched_setscheduler__doc__,
4793"sched_setscheduler(pid, policy, param)\n\n\
4794Set the scheduling policy, *policy*, for *pid*.\n\
4795If *pid* is 0, the calling process is changed.\n\
4796*param* is an instance of sched_param.");
4797
4798static PyObject *
4799posix_sched_setscheduler(PyObject *self, PyObject *args)
4800{
4801 pid_t pid;
4802 int policy;
4803 struct sched_param param;
4804
4805 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
4806 &pid, &policy, &convert_sched_param, &param))
4807 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02004808
4809 /*
Jesus Cea54b01492011-09-10 01:53:19 +02004810 ** sched_setscheduler() returns 0 in Linux, but the previous
4811 ** scheduling policy under Solaris/Illumos, and others.
4812 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02004813 */
4814 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004815 return posix_error();
4816 Py_RETURN_NONE;
4817}
4818
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004819#endif
4820
4821#ifdef HAVE_SCHED_SETPARAM
4822
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004823PyDoc_STRVAR(posix_sched_getparam__doc__,
4824"sched_getparam(pid) -> sched_param\n\n\
4825Returns scheduling parameters for the process with *pid* as an instance of the\n\
4826sched_param class. A PID of 0 means the calling process.");
4827
4828static PyObject *
4829posix_sched_getparam(PyObject *self, PyObject *args)
4830{
4831 pid_t pid;
4832 struct sched_param param;
4833 PyObject *res, *priority;
4834
4835 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
4836 return NULL;
4837 if (sched_getparam(pid, &param))
4838 return posix_error();
4839 res = PyStructSequence_New(&SchedParamType);
4840 if (!res)
4841 return NULL;
4842 priority = PyLong_FromLong(param.sched_priority);
4843 if (!priority) {
4844 Py_DECREF(res);
4845 return NULL;
4846 }
4847 PyStructSequence_SET_ITEM(res, 0, priority);
4848 return res;
4849}
4850
4851PyDoc_STRVAR(posix_sched_setparam__doc__,
4852"sched_setparam(pid, param)\n\n\
4853Set scheduling parameters for a process with PID *pid*.\n\
4854A PID of 0 means the calling process.");
4855
4856static PyObject *
4857posix_sched_setparam(PyObject *self, PyObject *args)
4858{
4859 pid_t pid;
4860 struct sched_param param;
4861
4862 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
4863 &pid, &convert_sched_param, &param))
4864 return NULL;
4865 if (sched_setparam(pid, &param))
4866 return posix_error();
4867 Py_RETURN_NONE;
4868}
4869
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004870#endif
4871
4872#ifdef HAVE_SCHED_RR_GET_INTERVAL
4873
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004874PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
4875"sched_rr_get_interval(pid) -> float\n\n\
4876Return the round-robin quantum for the process with PID *pid* in seconds.");
4877
4878static PyObject *
4879posix_sched_rr_get_interval(PyObject *self, PyObject *args)
4880{
4881 pid_t pid;
4882 struct timespec interval;
4883
4884 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
4885 return NULL;
4886 if (sched_rr_get_interval(pid, &interval))
4887 return posix_error();
4888 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
4889}
4890
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004891#endif
4892
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004893PyDoc_STRVAR(posix_sched_yield__doc__,
4894"sched_yield()\n\n\
4895Voluntarily relinquish the CPU.");
4896
4897static PyObject *
4898posix_sched_yield(PyObject *self, PyObject *noargs)
4899{
4900 if (sched_yield())
4901 return posix_error();
4902 Py_RETURN_NONE;
4903}
4904
Benjamin Peterson2740af82011-08-02 17:41:34 -05004905#ifdef HAVE_SCHED_SETAFFINITY
4906
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004907typedef struct {
4908 PyObject_HEAD;
4909 Py_ssize_t size;
4910 int ncpus;
4911 cpu_set_t *set;
4912} Py_cpu_set;
4913
4914static PyTypeObject cpu_set_type;
4915
4916static void
4917cpu_set_dealloc(Py_cpu_set *set)
4918{
4919 assert(set->set);
4920 CPU_FREE(set->set);
4921 Py_TYPE(set)->tp_free(set);
4922}
4923
4924static Py_cpu_set *
4925make_new_cpu_set(PyTypeObject *type, Py_ssize_t size)
4926{
4927 Py_cpu_set *set;
4928
4929 if (size < 0) {
4930 PyErr_SetString(PyExc_ValueError, "negative size");
4931 return NULL;
4932 }
4933 set = (Py_cpu_set *)type->tp_alloc(type, 0);
4934 if (!set)
4935 return NULL;
4936 set->ncpus = size;
4937 set->size = CPU_ALLOC_SIZE(size);
4938 set->set = CPU_ALLOC(size);
4939 if (!set->set) {
4940 type->tp_free(set);
4941 PyErr_NoMemory();
4942 return NULL;
4943 }
4944 CPU_ZERO_S(set->size, set->set);
4945 return set;
4946}
4947
4948static PyObject *
4949cpu_set_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
4950{
4951 int size;
4952
4953 if (!_PyArg_NoKeywords("cpu_set()", kwargs) ||
4954 !PyArg_ParseTuple(args, "i:cpu_set", &size))
4955 return NULL;
4956 return (PyObject *)make_new_cpu_set(type, size);
4957}
4958
4959static PyObject *
4960cpu_set_repr(Py_cpu_set *set)
4961{
4962 return PyUnicode_FromFormat("<cpu_set with %li entries>", set->ncpus);
Victor Stinner63941882011-09-29 00:42:28 +02004963}
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004964
4965static Py_ssize_t
4966cpu_set_len(Py_cpu_set *set)
4967{
4968 return set->ncpus;
4969}
4970
4971static int
4972_get_cpu(Py_cpu_set *set, const char *requester, PyObject *args)
4973{
4974 int cpu;
4975 if (!PyArg_ParseTuple(args, requester, &cpu))
4976 return -1;
4977 if (cpu < 0) {
4978 PyErr_SetString(PyExc_ValueError, "cpu < 0 not valid");
4979 return -1;
4980 }
4981 if (cpu >= set->ncpus) {
4982 PyErr_SetString(PyExc_ValueError, "cpu too large for set");
4983 return -1;
4984 }
4985 return cpu;
4986}
4987
4988PyDoc_STRVAR(cpu_set_set_doc,
4989"cpu_set.set(i)\n\n\
4990Add CPU *i* to the set.");
4991
4992static PyObject *
4993cpu_set_set(Py_cpu_set *set, PyObject *args)
4994{
4995 int cpu = _get_cpu(set, "i|set", args);
4996 if (cpu == -1)
4997 return NULL;
4998 CPU_SET_S(cpu, set->size, set->set);
4999 Py_RETURN_NONE;
5000}
5001
5002PyDoc_STRVAR(cpu_set_count_doc,
5003"cpu_set.count() -> int\n\n\
5004Return the number of CPUs active in the set.");
5005
5006static PyObject *
5007cpu_set_count(Py_cpu_set *set, PyObject *noargs)
5008{
5009 return PyLong_FromLong(CPU_COUNT_S(set->size, set->set));
5010}
5011
5012PyDoc_STRVAR(cpu_set_clear_doc,
5013"cpu_set.clear(i)\n\n\
5014Remove CPU *i* from the set.");
5015
5016static PyObject *
5017cpu_set_clear(Py_cpu_set *set, PyObject *args)
5018{
5019 int cpu = _get_cpu(set, "i|clear", args);
5020 if (cpu == -1)
5021 return NULL;
5022 CPU_CLR_S(cpu, set->size, set->set);
5023 Py_RETURN_NONE;
5024}
5025
5026PyDoc_STRVAR(cpu_set_isset_doc,
5027"cpu_set.isset(i) -> bool\n\n\
5028Test if CPU *i* is in the set.");
5029
5030static PyObject *
5031cpu_set_isset(Py_cpu_set *set, PyObject *args)
5032{
5033 int cpu = _get_cpu(set, "i|isset", args);
5034 if (cpu == -1)
5035 return NULL;
5036 if (CPU_ISSET_S(cpu, set->size, set->set))
5037 Py_RETURN_TRUE;
5038 Py_RETURN_FALSE;
5039}
5040
5041PyDoc_STRVAR(cpu_set_zero_doc,
5042"cpu_set.zero()\n\n\
5043Clear the cpu_set.");
5044
5045static PyObject *
5046cpu_set_zero(Py_cpu_set *set, PyObject *noargs)
5047{
5048 CPU_ZERO_S(set->size, set->set);
5049 Py_RETURN_NONE;
5050}
5051
5052static PyObject *
5053cpu_set_richcompare(Py_cpu_set *set, Py_cpu_set *other, int op)
5054{
5055 int eq;
5056
Brian Curtindfc80e32011-08-10 20:28:54 -05005057 if ((op != Py_EQ && op != Py_NE) || Py_TYPE(other) != &cpu_set_type)
5058 Py_RETURN_NOTIMPLEMENTED;
5059
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005060 eq = set->ncpus == other->ncpus && CPU_EQUAL_S(set->size, set->set, other->set);
5061 if ((op == Py_EQ) ? eq : !eq)
5062 Py_RETURN_TRUE;
5063 else
5064 Py_RETURN_FALSE;
5065}
5066
5067#define CPU_SET_BINOP(name, op) \
5068 static PyObject * \
5069 do_cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right, Py_cpu_set *res) { \
5070 if (res) { \
5071 Py_INCREF(res); \
5072 } \
5073 else { \
Benjamin Petersone870fe62011-08-02 17:44:26 -05005074 res = make_new_cpu_set(&cpu_set_type, left->ncpus); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005075 if (!res) \
5076 return NULL; \
5077 } \
Benjamin Peterson9b374bf2011-08-02 18:22:30 -05005078 if (Py_TYPE(right) != &cpu_set_type || left->ncpus != right->ncpus) { \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005079 Py_DECREF(res); \
Brian Curtindfc80e32011-08-10 20:28:54 -05005080 Py_RETURN_NOTIMPLEMENTED; \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005081 } \
Benjamin Peterson8f7bdd32011-08-02 18:34:30 -05005082 assert(left->size == right->size && right->size == res->size); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005083 op(res->size, res->set, left->set, right->set); \
5084 return (PyObject *)res; \
5085 } \
5086 static PyObject * \
5087 cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right) { \
5088 return do_cpu_set_##name(left, right, NULL); \
5089 } \
5090 static PyObject * \
5091 cpu_set_i##name(Py_cpu_set *left, Py_cpu_set *right) { \
5092 return do_cpu_set_##name(left, right, left); \
5093 } \
5094
5095CPU_SET_BINOP(and, CPU_AND_S)
5096CPU_SET_BINOP(or, CPU_OR_S)
5097CPU_SET_BINOP(xor, CPU_XOR_S)
5098#undef CPU_SET_BINOP
5099
5100PyDoc_STRVAR(cpu_set_doc,
5101"cpu_set(size)\n\n\
5102Create an empty mask of CPUs.");
5103
5104static PyNumberMethods cpu_set_as_number = {
5105 0, /*nb_add*/
5106 0, /*nb_subtract*/
5107 0, /*nb_multiply*/
5108 0, /*nb_remainder*/
5109 0, /*nb_divmod*/
5110 0, /*nb_power*/
5111 0, /*nb_negative*/
5112 0, /*nb_positive*/
5113 0, /*nb_absolute*/
5114 0, /*nb_bool*/
5115 0, /*nb_invert*/
5116 0, /*nb_lshift*/
5117 0, /*nb_rshift*/
5118 (binaryfunc)cpu_set_and, /*nb_and*/
5119 (binaryfunc)cpu_set_xor, /*nb_xor*/
5120 (binaryfunc)cpu_set_or, /*nb_or*/
5121 0, /*nb_int*/
5122 0, /*nb_reserved*/
5123 0, /*nb_float*/
5124 0, /*nb_inplace_add*/
5125 0, /*nb_inplace_subtract*/
5126 0, /*nb_inplace_multiply*/
5127 0, /*nb_inplace_remainder*/
5128 0, /*nb_inplace_power*/
5129 0, /*nb_inplace_lshift*/
5130 0, /*nb_inplace_rshift*/
5131 (binaryfunc)cpu_set_iand, /*nb_inplace_and*/
5132 (binaryfunc)cpu_set_ixor, /*nb_inplace_xor*/
5133 (binaryfunc)cpu_set_ior, /*nb_inplace_or*/
5134};
5135
5136static PySequenceMethods cpu_set_as_sequence = {
5137 (lenfunc)cpu_set_len, /* sq_length */
5138};
5139
5140static PyMethodDef cpu_set_methods[] = {
5141 {"clear", (PyCFunction)cpu_set_clear, METH_VARARGS, cpu_set_clear_doc},
5142 {"count", (PyCFunction)cpu_set_count, METH_NOARGS, cpu_set_count_doc},
5143 {"isset", (PyCFunction)cpu_set_isset, METH_VARARGS, cpu_set_isset_doc},
5144 {"set", (PyCFunction)cpu_set_set, METH_VARARGS, cpu_set_set_doc},
5145 {"zero", (PyCFunction)cpu_set_zero, METH_NOARGS, cpu_set_zero_doc},
5146 {NULL, NULL} /* sentinel */
5147};
5148
5149static PyTypeObject cpu_set_type = {
5150 PyVarObject_HEAD_INIT(&PyType_Type, 0)
5151 "posix.cpu_set", /* tp_name */
5152 sizeof(Py_cpu_set), /* tp_basicsize */
5153 0, /* tp_itemsize */
5154 /* methods */
5155 (destructor)cpu_set_dealloc, /* tp_dealloc */
5156 0, /* tp_print */
5157 0, /* tp_getattr */
5158 0, /* tp_setattr */
5159 0, /* tp_reserved */
5160 (reprfunc)cpu_set_repr, /* tp_repr */
5161 &cpu_set_as_number, /* tp_as_number */
5162 &cpu_set_as_sequence, /* tp_as_sequence */
5163 0, /* tp_as_mapping */
5164 PyObject_HashNotImplemented, /* tp_hash */
5165 0, /* tp_call */
5166 0, /* tp_str */
5167 PyObject_GenericGetAttr, /* tp_getattro */
5168 0, /* tp_setattro */
5169 0, /* tp_as_buffer */
5170 Py_TPFLAGS_DEFAULT, /* tp_flags */
5171 cpu_set_doc, /* tp_doc */
5172 0, /* tp_traverse */
5173 0, /* tp_clear */
5174 (richcmpfunc)cpu_set_richcompare, /* tp_richcompare */
5175 0, /* tp_weaklistoffset */
5176 0, /* tp_iter */
5177 0, /* tp_iternext */
5178 cpu_set_methods, /* tp_methods */
5179 0, /* tp_members */
5180 0, /* tp_getset */
5181 0, /* tp_base */
5182 0, /* tp_dict */
5183 0, /* tp_descr_get */
5184 0, /* tp_descr_set */
5185 0, /* tp_dictoffset */
5186 0, /* tp_init */
5187 PyType_GenericAlloc, /* tp_alloc */
5188 cpu_set_new, /* tp_new */
5189 PyObject_Del, /* tp_free */
5190};
5191
5192PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5193"sched_setaffinity(pid, cpu_set)\n\n\
5194Set the affinity of the process with PID *pid* to *cpu_set*.");
5195
5196static PyObject *
5197posix_sched_setaffinity(PyObject *self, PyObject *args)
5198{
5199 pid_t pid;
5200 Py_cpu_set *cpu_set;
5201
Benjamin Petersona17a5d62011-08-09 16:49:13 -05005202 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O!:sched_setaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005203 &pid, &cpu_set_type, &cpu_set))
5204 return NULL;
5205 if (sched_setaffinity(pid, cpu_set->size, cpu_set->set))
5206 return posix_error();
5207 Py_RETURN_NONE;
5208}
5209
5210PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5211"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5212Return the affinity of the process with PID *pid*.\n\
5213The returned cpu_set will be of size *ncpus*.");
5214
5215static PyObject *
5216posix_sched_getaffinity(PyObject *self, PyObject *args)
5217{
5218 pid_t pid;
5219 int ncpus;
5220 Py_cpu_set *res;
5221
Benjamin Peterson7ac92142011-08-03 08:54:26 -05005222 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:sched_getaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005223 &pid, &ncpus))
5224 return NULL;
5225 res = make_new_cpu_set(&cpu_set_type, ncpus);
5226 if (!res)
5227 return NULL;
5228 if (sched_getaffinity(pid, res->size, res->set)) {
5229 Py_DECREF(res);
5230 return posix_error();
5231 }
5232 return (PyObject *)res;
5233}
5234
Benjamin Peterson2740af82011-08-02 17:41:34 -05005235#endif /* HAVE_SCHED_SETAFFINITY */
5236
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005237#endif /* HAVE_SCHED_H */
5238
Neal Norwitzb59798b2003-03-21 01:43:31 +00005239/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005240/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5241#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005242#define DEV_PTY_FILE "/dev/ptc"
5243#define HAVE_DEV_PTMX
5244#else
5245#define DEV_PTY_FILE "/dev/ptmx"
5246#endif
5247
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005248#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005249#ifdef HAVE_PTY_H
5250#include <pty.h>
5251#else
5252#ifdef HAVE_LIBUTIL_H
5253#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005254#else
5255#ifdef HAVE_UTIL_H
5256#include <util.h>
5257#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005258#endif /* HAVE_LIBUTIL_H */
5259#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005260#ifdef HAVE_STROPTS_H
5261#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005262#endif
5263#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005264
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005265#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005266PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005267"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005268Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005269
5270static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005271posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005272{
Victor Stinner8c62be82010-05-06 00:08:46 +00005273 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005274#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005275 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005276#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005277#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005278 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005279#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005280 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005281#endif
5282#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005283
Thomas Wouters70c21a12000-07-14 14:28:33 +00005284#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005285 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
5286 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005287#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005288 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5289 if (slave_name == NULL)
5290 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00005291
Victor Stinner8c62be82010-05-06 00:08:46 +00005292 slave_fd = open(slave_name, O_RDWR);
5293 if (slave_fd < 0)
5294 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005295#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005296 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
5297 if (master_fd < 0)
5298 return posix_error();
5299 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
5300 /* change permission of slave */
5301 if (grantpt(master_fd) < 0) {
5302 PyOS_setsig(SIGCHLD, sig_saved);
5303 return posix_error();
5304 }
5305 /* unlock slave */
5306 if (unlockpt(master_fd) < 0) {
5307 PyOS_setsig(SIGCHLD, sig_saved);
5308 return posix_error();
5309 }
5310 PyOS_setsig(SIGCHLD, sig_saved);
5311 slave_name = ptsname(master_fd); /* get name of slave */
5312 if (slave_name == NULL)
5313 return posix_error();
5314 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
5315 if (slave_fd < 0)
5316 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005317#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005318 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5319 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005320#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005321 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005322#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005323#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005324#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005325
Victor Stinner8c62be82010-05-06 00:08:46 +00005326 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005327
Fred Drake8cef4cf2000-06-28 16:40:38 +00005328}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005329#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005330
5331#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005332PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005333"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00005334Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
5335Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005336To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005337
5338static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005339posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005340{
Victor Stinner8c62be82010-05-06 00:08:46 +00005341 int master_fd = -1, result = 0;
5342 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005343
Victor Stinner8c62be82010-05-06 00:08:46 +00005344 _PyImport_AcquireLock();
5345 pid = forkpty(&master_fd, NULL, NULL, NULL);
5346 if (pid == 0) {
5347 /* child: this clobbers and resets the import lock. */
5348 PyOS_AfterFork();
5349 } else {
5350 /* parent: release the import lock. */
5351 result = _PyImport_ReleaseLock();
5352 }
5353 if (pid == -1)
5354 return posix_error();
5355 if (result < 0) {
5356 /* Don't clobber the OSError if the fork failed. */
5357 PyErr_SetString(PyExc_RuntimeError,
5358 "not holding the import lock");
5359 return NULL;
5360 }
5361 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005362}
5363#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005364
Ross Lagerwall7807c352011-03-17 20:20:30 +02005365
Guido van Rossumad0ee831995-03-01 10:34:45 +00005366#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005367PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005368"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005369Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005370
Barry Warsaw53699e91996-12-10 23:23:01 +00005371static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005372posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005373{
Victor Stinner8c62be82010-05-06 00:08:46 +00005374 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005375}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005376#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005377
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005378
Guido van Rossumad0ee831995-03-01 10:34:45 +00005379#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005380PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005381"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005382Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005383
Barry Warsaw53699e91996-12-10 23:23:01 +00005384static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005385posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005386{
Victor Stinner8c62be82010-05-06 00:08:46 +00005387 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005388}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005389#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005390
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005391
Guido van Rossumad0ee831995-03-01 10:34:45 +00005392#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005393PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005394"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005395Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005396
Barry Warsaw53699e91996-12-10 23:23:01 +00005397static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005398posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005399{
Victor Stinner8c62be82010-05-06 00:08:46 +00005400 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005401}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005402#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005403
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005404
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005405PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005406"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005407Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005408
Barry Warsaw53699e91996-12-10 23:23:01 +00005409static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005410posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005411{
Victor Stinner8c62be82010-05-06 00:08:46 +00005412 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005413}
5414
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005415#ifdef HAVE_GETGROUPLIST
5416PyDoc_STRVAR(posix_getgrouplist__doc__,
5417"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5418Returns a list of groups to which a user belongs.\n\n\
5419 user: username to lookup\n\
5420 group: base group id of the user");
5421
5422static PyObject *
5423posix_getgrouplist(PyObject *self, PyObject *args)
5424{
5425#ifdef NGROUPS_MAX
5426#define MAX_GROUPS NGROUPS_MAX
5427#else
5428 /* defined to be 16 on Solaris7, so this should be a small number */
5429#define MAX_GROUPS 64
5430#endif
5431
5432 const char *user;
5433 int i, ngroups;
5434 PyObject *list;
5435#ifdef __APPLE__
5436 int *groups, basegid;
5437#else
5438 gid_t *groups, basegid;
5439#endif
5440 ngroups = MAX_GROUPS;
5441
5442 if (!PyArg_ParseTuple(args, "si", &user, &basegid))
5443 return NULL;
5444
5445#ifdef __APPLE__
5446 groups = PyMem_Malloc(ngroups * sizeof(int));
5447#else
5448 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
5449#endif
5450 if (groups == NULL)
5451 return PyErr_NoMemory();
5452
5453 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
5454 PyMem_Del(groups);
5455 return posix_error();
5456 }
5457
5458 list = PyList_New(ngroups);
5459 if (list == NULL) {
5460 PyMem_Del(groups);
5461 return NULL;
5462 }
5463
5464 for (i = 0; i < ngroups; i++) {
5465 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
5466 if (o == NULL) {
5467 Py_DECREF(list);
5468 PyMem_Del(groups);
5469 return NULL;
5470 }
5471 PyList_SET_ITEM(list, i, o);
5472 }
5473
5474 PyMem_Del(groups);
5475
5476 return list;
5477}
5478#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005479
Fred Drakec9680921999-12-13 16:37:25 +00005480#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005481PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005482"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005483Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00005484
5485static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005486posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00005487{
5488 PyObject *result = NULL;
5489
Fred Drakec9680921999-12-13 16:37:25 +00005490#ifdef NGROUPS_MAX
5491#define MAX_GROUPS NGROUPS_MAX
5492#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005493 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00005494#define MAX_GROUPS 64
5495#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005496 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005497
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005498 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005499 * This is a helper variable to store the intermediate result when
5500 * that happens.
5501 *
5502 * To keep the code readable the OSX behaviour is unconditional,
5503 * according to the POSIX spec this should be safe on all unix-y
5504 * systems.
5505 */
5506 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005507 int n;
Fred Drakec9680921999-12-13 16:37:25 +00005508
Victor Stinner8c62be82010-05-06 00:08:46 +00005509 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005510 if (n < 0) {
5511 if (errno == EINVAL) {
5512 n = getgroups(0, NULL);
5513 if (n == -1) {
5514 return posix_error();
5515 }
5516 if (n == 0) {
5517 /* Avoid malloc(0) */
5518 alt_grouplist = grouplist;
5519 } else {
5520 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
5521 if (alt_grouplist == NULL) {
5522 errno = EINVAL;
5523 return posix_error();
5524 }
5525 n = getgroups(n, alt_grouplist);
5526 if (n == -1) {
5527 PyMem_Free(alt_grouplist);
5528 return posix_error();
5529 }
5530 }
5531 } else {
5532 return posix_error();
5533 }
5534 }
5535 result = PyList_New(n);
5536 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005537 int i;
5538 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005539 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00005540 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00005541 Py_DECREF(result);
5542 result = NULL;
5543 break;
Fred Drakec9680921999-12-13 16:37:25 +00005544 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005545 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00005546 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005547 }
5548
5549 if (alt_grouplist != grouplist) {
5550 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005551 }
Neal Norwitze241ce82003-02-17 18:17:05 +00005552
Fred Drakec9680921999-12-13 16:37:25 +00005553 return result;
5554}
5555#endif
5556
Antoine Pitroub7572f02009-12-02 20:46:48 +00005557#ifdef HAVE_INITGROUPS
5558PyDoc_STRVAR(posix_initgroups__doc__,
5559"initgroups(username, gid) -> None\n\n\
5560Call the system initgroups() to initialize the group access list with all of\n\
5561the groups of which the specified username is a member, plus the specified\n\
5562group id.");
5563
5564static PyObject *
5565posix_initgroups(PyObject *self, PyObject *args)
5566{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005567 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00005568 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005569 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00005570 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005571
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005572 if (!PyArg_ParseTuple(args, "O&l:initgroups",
5573 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00005574 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005575 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005576
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005577 res = initgroups(username, (gid_t) gid);
5578 Py_DECREF(oname);
5579 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00005580 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005581
Victor Stinner8c62be82010-05-06 00:08:46 +00005582 Py_INCREF(Py_None);
5583 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005584}
5585#endif
5586
Martin v. Löwis606edc12002-06-13 21:09:11 +00005587#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005588PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005589"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005590Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00005591
5592static PyObject *
5593posix_getpgid(PyObject *self, PyObject *args)
5594{
Victor Stinner8c62be82010-05-06 00:08:46 +00005595 pid_t pid, pgid;
5596 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
5597 return NULL;
5598 pgid = getpgid(pid);
5599 if (pgid < 0)
5600 return posix_error();
5601 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00005602}
5603#endif /* HAVE_GETPGID */
5604
5605
Guido van Rossumb6775db1994-08-01 11:34:53 +00005606#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005607PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005608"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005609Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005610
Barry Warsaw53699e91996-12-10 23:23:01 +00005611static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005612posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00005613{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005614#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005615 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005616#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005617 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005618#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00005619}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005620#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00005621
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005622
Guido van Rossumb6775db1994-08-01 11:34:53 +00005623#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005624PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005625"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00005626Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005627
Barry Warsaw53699e91996-12-10 23:23:01 +00005628static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005629posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005630{
Guido van Rossum64933891994-10-20 21:56:42 +00005631#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005632 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005633#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005634 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005635#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005636 return posix_error();
5637 Py_INCREF(Py_None);
5638 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005639}
5640
Guido van Rossumb6775db1994-08-01 11:34:53 +00005641#endif /* HAVE_SETPGRP */
5642
Guido van Rossumad0ee831995-03-01 10:34:45 +00005643#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005644
5645#ifdef MS_WINDOWS
5646#include <tlhelp32.h>
5647
5648static PyObject*
5649win32_getppid()
5650{
5651 HANDLE snapshot;
5652 pid_t mypid;
5653 PyObject* result = NULL;
5654 BOOL have_record;
5655 PROCESSENTRY32 pe;
5656
5657 mypid = getpid(); /* This function never fails */
5658
5659 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
5660 if (snapshot == INVALID_HANDLE_VALUE)
5661 return PyErr_SetFromWindowsErr(GetLastError());
5662
5663 pe.dwSize = sizeof(pe);
5664 have_record = Process32First(snapshot, &pe);
5665 while (have_record) {
5666 if (mypid == (pid_t)pe.th32ProcessID) {
5667 /* We could cache the ulong value in a static variable. */
5668 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
5669 break;
5670 }
5671
5672 have_record = Process32Next(snapshot, &pe);
5673 }
5674
5675 /* If our loop exits and our pid was not found (result will be NULL)
5676 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
5677 * error anyway, so let's raise it. */
5678 if (!result)
5679 result = PyErr_SetFromWindowsErr(GetLastError());
5680
5681 CloseHandle(snapshot);
5682
5683 return result;
5684}
5685#endif /*MS_WINDOWS*/
5686
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005687PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005688"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005689Return the parent's process id. If the parent process has already exited,\n\
5690Windows machines will still return its id; others systems will return the id\n\
5691of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005692
Barry Warsaw53699e91996-12-10 23:23:01 +00005693static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005694posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005695{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005696#ifdef MS_WINDOWS
5697 return win32_getppid();
5698#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005699 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00005700#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005701}
5702#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005703
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005704
Fred Drake12c6e2d1999-12-14 21:25:03 +00005705#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005706PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005707"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005708Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00005709
5710static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005711posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005712{
Victor Stinner8c62be82010-05-06 00:08:46 +00005713 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005714#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005715 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02005716 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005717
5718 if (GetUserNameW(user_name, &num_chars)) {
5719 /* num_chars is the number of unicode chars plus null terminator */
5720 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005721 }
5722 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005723 result = PyErr_SetFromWindowsErr(GetLastError());
5724#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005725 char *name;
5726 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005727
Victor Stinner8c62be82010-05-06 00:08:46 +00005728 errno = 0;
5729 name = getlogin();
5730 if (name == NULL) {
5731 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00005732 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00005733 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00005734 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00005735 }
5736 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00005737 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00005738 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005739#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00005740 return result;
5741}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005742#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005743
Guido van Rossumad0ee831995-03-01 10:34:45 +00005744#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005745PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005746"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005747Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005748
Barry Warsaw53699e91996-12-10 23:23:01 +00005749static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005750posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005751{
Victor Stinner8c62be82010-05-06 00:08:46 +00005752 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005753}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005754#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005755
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005756
Guido van Rossumad0ee831995-03-01 10:34:45 +00005757#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005758PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005759"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005760Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005761
Barry Warsaw53699e91996-12-10 23:23:01 +00005762static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005763posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005764{
Victor Stinner8c62be82010-05-06 00:08:46 +00005765 pid_t pid;
5766 int sig;
5767 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
5768 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005769#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005770 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
5771 APIRET rc;
5772 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005773 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005774
5775 } else if (sig == XCPT_SIGNAL_KILLPROC) {
5776 APIRET rc;
5777 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005778 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005779
5780 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00005781 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005782#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005783 if (kill(pid, sig) == -1)
5784 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005785#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005786 Py_INCREF(Py_None);
5787 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00005788}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005789#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005790
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005791#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005792PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005793"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005794Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005795
5796static PyObject *
5797posix_killpg(PyObject *self, PyObject *args)
5798{
Victor Stinner8c62be82010-05-06 00:08:46 +00005799 int sig;
5800 pid_t pgid;
5801 /* XXX some man pages make the `pgid` parameter an int, others
5802 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
5803 take the same type. Moreover, pid_t is always at least as wide as
5804 int (else compilation of this module fails), which is safe. */
5805 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
5806 return NULL;
5807 if (killpg(pgid, sig) == -1)
5808 return posix_error();
5809 Py_INCREF(Py_None);
5810 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005811}
5812#endif
5813
Brian Curtineb24d742010-04-12 17:16:38 +00005814#ifdef MS_WINDOWS
5815PyDoc_STRVAR(win32_kill__doc__,
5816"kill(pid, sig)\n\n\
5817Kill a process with a signal.");
5818
5819static PyObject *
5820win32_kill(PyObject *self, PyObject *args)
5821{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00005822 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00005823 DWORD pid, sig, err;
5824 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00005825
Victor Stinner8c62be82010-05-06 00:08:46 +00005826 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
5827 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00005828
Victor Stinner8c62be82010-05-06 00:08:46 +00005829 /* Console processes which share a common console can be sent CTRL+C or
5830 CTRL+BREAK events, provided they handle said events. */
5831 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
5832 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
5833 err = GetLastError();
5834 PyErr_SetFromWindowsErr(err);
5835 }
5836 else
5837 Py_RETURN_NONE;
5838 }
Brian Curtineb24d742010-04-12 17:16:38 +00005839
Victor Stinner8c62be82010-05-06 00:08:46 +00005840 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
5841 attempt to open and terminate the process. */
5842 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
5843 if (handle == NULL) {
5844 err = GetLastError();
5845 return PyErr_SetFromWindowsErr(err);
5846 }
Brian Curtineb24d742010-04-12 17:16:38 +00005847
Victor Stinner8c62be82010-05-06 00:08:46 +00005848 if (TerminateProcess(handle, sig) == 0) {
5849 err = GetLastError();
5850 result = PyErr_SetFromWindowsErr(err);
5851 } else {
5852 Py_INCREF(Py_None);
5853 result = Py_None;
5854 }
Brian Curtineb24d742010-04-12 17:16:38 +00005855
Victor Stinner8c62be82010-05-06 00:08:46 +00005856 CloseHandle(handle);
5857 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00005858}
5859#endif /* MS_WINDOWS */
5860
Guido van Rossumc0125471996-06-28 18:55:32 +00005861#ifdef HAVE_PLOCK
5862
5863#ifdef HAVE_SYS_LOCK_H
5864#include <sys/lock.h>
5865#endif
5866
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005867PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005868"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005869Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005870
Barry Warsaw53699e91996-12-10 23:23:01 +00005871static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005872posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00005873{
Victor Stinner8c62be82010-05-06 00:08:46 +00005874 int op;
5875 if (!PyArg_ParseTuple(args, "i:plock", &op))
5876 return NULL;
5877 if (plock(op) == -1)
5878 return posix_error();
5879 Py_INCREF(Py_None);
5880 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00005881}
5882#endif
5883
Guido van Rossumb6775db1994-08-01 11:34:53 +00005884#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005885PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005886"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005887Set the current process's user id.");
5888
Barry Warsaw53699e91996-12-10 23:23:01 +00005889static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005890posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005891{
Victor Stinner8c62be82010-05-06 00:08:46 +00005892 long uid_arg;
5893 uid_t uid;
5894 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
5895 return NULL;
5896 uid = uid_arg;
5897 if (uid != uid_arg) {
5898 PyErr_SetString(PyExc_OverflowError, "user id too big");
5899 return NULL;
5900 }
5901 if (setuid(uid) < 0)
5902 return posix_error();
5903 Py_INCREF(Py_None);
5904 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005905}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005906#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005907
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005908
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005909#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005910PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005911"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005912Set the current process's effective user id.");
5913
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005914static PyObject *
5915posix_seteuid (PyObject *self, PyObject *args)
5916{
Victor Stinner8c62be82010-05-06 00:08:46 +00005917 long euid_arg;
5918 uid_t euid;
5919 if (!PyArg_ParseTuple(args, "l", &euid_arg))
5920 return NULL;
5921 euid = euid_arg;
5922 if (euid != euid_arg) {
5923 PyErr_SetString(PyExc_OverflowError, "user id too big");
5924 return NULL;
5925 }
5926 if (seteuid(euid) < 0) {
5927 return posix_error();
5928 } else {
5929 Py_INCREF(Py_None);
5930 return Py_None;
5931 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005932}
5933#endif /* HAVE_SETEUID */
5934
5935#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005936PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005937"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005938Set the current process's effective group id.");
5939
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005940static PyObject *
5941posix_setegid (PyObject *self, PyObject *args)
5942{
Victor Stinner8c62be82010-05-06 00:08:46 +00005943 long egid_arg;
5944 gid_t egid;
5945 if (!PyArg_ParseTuple(args, "l", &egid_arg))
5946 return NULL;
5947 egid = egid_arg;
5948 if (egid != egid_arg) {
5949 PyErr_SetString(PyExc_OverflowError, "group id too big");
5950 return NULL;
5951 }
5952 if (setegid(egid) < 0) {
5953 return posix_error();
5954 } else {
5955 Py_INCREF(Py_None);
5956 return Py_None;
5957 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005958}
5959#endif /* HAVE_SETEGID */
5960
5961#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005962PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005963"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005964Set the current process's real and effective user ids.");
5965
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005966static PyObject *
5967posix_setreuid (PyObject *self, PyObject *args)
5968{
Victor Stinner8c62be82010-05-06 00:08:46 +00005969 long ruid_arg, euid_arg;
5970 uid_t ruid, euid;
5971 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
5972 return NULL;
5973 if (ruid_arg == -1)
5974 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
5975 else
5976 ruid = ruid_arg; /* otherwise, assign from our long */
5977 if (euid_arg == -1)
5978 euid = (uid_t)-1;
5979 else
5980 euid = euid_arg;
5981 if ((euid_arg != -1 && euid != euid_arg) ||
5982 (ruid_arg != -1 && ruid != ruid_arg)) {
5983 PyErr_SetString(PyExc_OverflowError, "user id too big");
5984 return NULL;
5985 }
5986 if (setreuid(ruid, euid) < 0) {
5987 return posix_error();
5988 } else {
5989 Py_INCREF(Py_None);
5990 return Py_None;
5991 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005992}
5993#endif /* HAVE_SETREUID */
5994
5995#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005996PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005997"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005998Set the current process's real and effective group ids.");
5999
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006000static PyObject *
6001posix_setregid (PyObject *self, PyObject *args)
6002{
Victor Stinner8c62be82010-05-06 00:08:46 +00006003 long rgid_arg, egid_arg;
6004 gid_t rgid, egid;
6005 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
6006 return NULL;
6007 if (rgid_arg == -1)
6008 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
6009 else
6010 rgid = rgid_arg; /* otherwise, assign from our long */
6011 if (egid_arg == -1)
6012 egid = (gid_t)-1;
6013 else
6014 egid = egid_arg;
6015 if ((egid_arg != -1 && egid != egid_arg) ||
6016 (rgid_arg != -1 && rgid != rgid_arg)) {
6017 PyErr_SetString(PyExc_OverflowError, "group id too big");
6018 return NULL;
6019 }
6020 if (setregid(rgid, egid) < 0) {
6021 return posix_error();
6022 } else {
6023 Py_INCREF(Py_None);
6024 return Py_None;
6025 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006026}
6027#endif /* HAVE_SETREGID */
6028
Guido van Rossumb6775db1994-08-01 11:34:53 +00006029#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006030PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006031"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006032Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006033
Barry Warsaw53699e91996-12-10 23:23:01 +00006034static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006035posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006036{
Victor Stinner8c62be82010-05-06 00:08:46 +00006037 long gid_arg;
6038 gid_t gid;
6039 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
6040 return NULL;
6041 gid = gid_arg;
6042 if (gid != gid_arg) {
6043 PyErr_SetString(PyExc_OverflowError, "group id too big");
6044 return NULL;
6045 }
6046 if (setgid(gid) < 0)
6047 return posix_error();
6048 Py_INCREF(Py_None);
6049 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006050}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006051#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006052
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006053#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006054PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006055"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006056Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006057
6058static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006059posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006060{
Victor Stinner8c62be82010-05-06 00:08:46 +00006061 int i, len;
6062 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006063
Victor Stinner8c62be82010-05-06 00:08:46 +00006064 if (!PySequence_Check(groups)) {
6065 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6066 return NULL;
6067 }
6068 len = PySequence_Size(groups);
6069 if (len > MAX_GROUPS) {
6070 PyErr_SetString(PyExc_ValueError, "too many groups");
6071 return NULL;
6072 }
6073 for(i = 0; i < len; i++) {
6074 PyObject *elem;
6075 elem = PySequence_GetItem(groups, i);
6076 if (!elem)
6077 return NULL;
6078 if (!PyLong_Check(elem)) {
6079 PyErr_SetString(PyExc_TypeError,
6080 "groups must be integers");
6081 Py_DECREF(elem);
6082 return NULL;
6083 } else {
6084 unsigned long x = PyLong_AsUnsignedLong(elem);
6085 if (PyErr_Occurred()) {
6086 PyErr_SetString(PyExc_TypeError,
6087 "group id too big");
6088 Py_DECREF(elem);
6089 return NULL;
6090 }
6091 grouplist[i] = x;
6092 /* read back the value to see if it fitted in gid_t */
6093 if (grouplist[i] != x) {
6094 PyErr_SetString(PyExc_TypeError,
6095 "group id too big");
6096 Py_DECREF(elem);
6097 return NULL;
6098 }
6099 }
6100 Py_DECREF(elem);
6101 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006102
Victor Stinner8c62be82010-05-06 00:08:46 +00006103 if (setgroups(len, grouplist) < 0)
6104 return posix_error();
6105 Py_INCREF(Py_None);
6106 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006107}
6108#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006109
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006110#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6111static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006112wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006113{
Victor Stinner8c62be82010-05-06 00:08:46 +00006114 PyObject *result;
6115 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006116 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006117
Victor Stinner8c62be82010-05-06 00:08:46 +00006118 if (pid == -1)
6119 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006120
Victor Stinner8c62be82010-05-06 00:08:46 +00006121 if (struct_rusage == NULL) {
6122 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6123 if (m == NULL)
6124 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006125 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006126 Py_DECREF(m);
6127 if (struct_rusage == NULL)
6128 return NULL;
6129 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006130
Victor Stinner8c62be82010-05-06 00:08:46 +00006131 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6132 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6133 if (!result)
6134 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006135
6136#ifndef doubletime
6137#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6138#endif
6139
Victor Stinner8c62be82010-05-06 00:08:46 +00006140 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006141 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006142 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006143 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006144#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006145 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6146 SET_INT(result, 2, ru->ru_maxrss);
6147 SET_INT(result, 3, ru->ru_ixrss);
6148 SET_INT(result, 4, ru->ru_idrss);
6149 SET_INT(result, 5, ru->ru_isrss);
6150 SET_INT(result, 6, ru->ru_minflt);
6151 SET_INT(result, 7, ru->ru_majflt);
6152 SET_INT(result, 8, ru->ru_nswap);
6153 SET_INT(result, 9, ru->ru_inblock);
6154 SET_INT(result, 10, ru->ru_oublock);
6155 SET_INT(result, 11, ru->ru_msgsnd);
6156 SET_INT(result, 12, ru->ru_msgrcv);
6157 SET_INT(result, 13, ru->ru_nsignals);
6158 SET_INT(result, 14, ru->ru_nvcsw);
6159 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006160#undef SET_INT
6161
Victor Stinner8c62be82010-05-06 00:08:46 +00006162 if (PyErr_Occurred()) {
6163 Py_DECREF(result);
6164 return NULL;
6165 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006166
Victor Stinner8c62be82010-05-06 00:08:46 +00006167 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006168}
6169#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6170
6171#ifdef HAVE_WAIT3
6172PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006173"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006174Wait for completion of a child process.");
6175
6176static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006177posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006178{
Victor Stinner8c62be82010-05-06 00:08:46 +00006179 pid_t pid;
6180 int options;
6181 struct rusage ru;
6182 WAIT_TYPE status;
6183 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006184
Victor Stinner4195b5c2012-02-08 23:03:19 +01006185 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006186 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006187
Victor Stinner8c62be82010-05-06 00:08:46 +00006188 Py_BEGIN_ALLOW_THREADS
6189 pid = wait3(&status, options, &ru);
6190 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006191
Victor Stinner4195b5c2012-02-08 23:03:19 +01006192 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006193}
6194#endif /* HAVE_WAIT3 */
6195
6196#ifdef HAVE_WAIT4
6197PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006198"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006199Wait for completion of a given child process.");
6200
6201static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006202posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006203{
Victor Stinner8c62be82010-05-06 00:08:46 +00006204 pid_t pid;
6205 int options;
6206 struct rusage ru;
6207 WAIT_TYPE status;
6208 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006209
Victor Stinner4195b5c2012-02-08 23:03:19 +01006210 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006211 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006212
Victor Stinner8c62be82010-05-06 00:08:46 +00006213 Py_BEGIN_ALLOW_THREADS
6214 pid = wait4(pid, &status, options, &ru);
6215 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006216
Victor Stinner4195b5c2012-02-08 23:03:19 +01006217 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006218}
6219#endif /* HAVE_WAIT4 */
6220
Ross Lagerwall7807c352011-03-17 20:20:30 +02006221#if defined(HAVE_WAITID) && !defined(__APPLE__)
6222PyDoc_STRVAR(posix_waitid__doc__,
6223"waitid(idtype, id, options) -> waitid_result\n\n\
6224Wait for the completion of one or more child processes.\n\n\
6225idtype can be P_PID, P_PGID or P_ALL.\n\
6226id specifies the pid to wait on.\n\
6227options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6228or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6229Returns either waitid_result or None if WNOHANG is specified and there are\n\
6230no children in a waitable state.");
6231
6232static PyObject *
6233posix_waitid(PyObject *self, PyObject *args)
6234{
6235 PyObject *result;
6236 idtype_t idtype;
6237 id_t id;
6238 int options, res;
6239 siginfo_t si;
6240 si.si_pid = 0;
6241 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6242 return NULL;
6243 Py_BEGIN_ALLOW_THREADS
6244 res = waitid(idtype, id, &si, options);
6245 Py_END_ALLOW_THREADS
6246 if (res == -1)
6247 return posix_error();
6248
6249 if (si.si_pid == 0)
6250 Py_RETURN_NONE;
6251
6252 result = PyStructSequence_New(&WaitidResultType);
6253 if (!result)
6254 return NULL;
6255
6256 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
6257 PyStructSequence_SET_ITEM(result, 1, PyLong_FromPid(si.si_uid));
6258 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6259 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6260 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6261 if (PyErr_Occurred()) {
6262 Py_DECREF(result);
6263 return NULL;
6264 }
6265
6266 return result;
6267}
6268#endif
6269
Guido van Rossumb6775db1994-08-01 11:34:53 +00006270#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006271PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006272"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006273Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006274
Barry Warsaw53699e91996-12-10 23:23:01 +00006275static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006276posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006277{
Victor Stinner8c62be82010-05-06 00:08:46 +00006278 pid_t pid;
6279 int options;
6280 WAIT_TYPE status;
6281 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006282
Victor Stinner8c62be82010-05-06 00:08:46 +00006283 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6284 return NULL;
6285 Py_BEGIN_ALLOW_THREADS
6286 pid = waitpid(pid, &status, options);
6287 Py_END_ALLOW_THREADS
6288 if (pid == -1)
6289 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006290
Victor Stinner8c62be82010-05-06 00:08:46 +00006291 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006292}
6293
Tim Petersab034fa2002-02-01 11:27:43 +00006294#elif defined(HAVE_CWAIT)
6295
6296/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006297PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006298"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006299"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006300
6301static PyObject *
6302posix_waitpid(PyObject *self, PyObject *args)
6303{
Victor Stinner8c62be82010-05-06 00:08:46 +00006304 Py_intptr_t pid;
6305 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006306
Victor Stinner8c62be82010-05-06 00:08:46 +00006307 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6308 return NULL;
6309 Py_BEGIN_ALLOW_THREADS
6310 pid = _cwait(&status, pid, options);
6311 Py_END_ALLOW_THREADS
6312 if (pid == -1)
6313 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006314
Victor Stinner8c62be82010-05-06 00:08:46 +00006315 /* shift the status left a byte so this is more like the POSIX waitpid */
6316 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006317}
6318#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006319
Guido van Rossumad0ee831995-03-01 10:34:45 +00006320#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006321PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006322"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006323Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006324
Barry Warsaw53699e91996-12-10 23:23:01 +00006325static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006326posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006327{
Victor Stinner8c62be82010-05-06 00:08:46 +00006328 pid_t pid;
6329 WAIT_TYPE status;
6330 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006331
Victor Stinner8c62be82010-05-06 00:08:46 +00006332 Py_BEGIN_ALLOW_THREADS
6333 pid = wait(&status);
6334 Py_END_ALLOW_THREADS
6335 if (pid == -1)
6336 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006337
Victor Stinner8c62be82010-05-06 00:08:46 +00006338 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006339}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006340#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006341
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006342
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006343PyDoc_STRVAR(posix_lstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006344"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006345Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006346
Barry Warsaw53699e91996-12-10 23:23:01 +00006347static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006348posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006349{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006350#ifdef HAVE_LSTAT
Victor Stinner4195b5c2012-02-08 23:03:19 +01006351 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006352#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006353#ifdef MS_WINDOWS
Victor Stinner4195b5c2012-02-08 23:03:19 +01006354 return posix_do_stat(self, args, "O&:lstat", win32_lstat, "U:lstat",
Brian Curtind40e6f72010-07-08 21:39:08 +00006355 win32_lstat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006356#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01006357 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006358#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006359#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006360}
6361
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006362
Guido van Rossumb6775db1994-08-01 11:34:53 +00006363#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006364PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006365"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006366Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006367
Barry Warsaw53699e91996-12-10 23:23:01 +00006368static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006369posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006370{
Victor Stinner8c62be82010-05-06 00:08:46 +00006371 PyObject* v;
6372 char buf[MAXPATHLEN];
6373 PyObject *opath;
6374 char *path;
6375 int n;
6376 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00006377
Victor Stinner8c62be82010-05-06 00:08:46 +00006378 if (!PyArg_ParseTuple(args, "O&:readlink",
6379 PyUnicode_FSConverter, &opath))
6380 return NULL;
6381 path = PyBytes_AsString(opath);
6382 v = PySequence_GetItem(args, 0);
6383 if (v == NULL) {
6384 Py_DECREF(opath);
6385 return NULL;
6386 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00006387
Victor Stinner8c62be82010-05-06 00:08:46 +00006388 if (PyUnicode_Check(v)) {
6389 arg_is_unicode = 1;
6390 }
6391 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00006392
Victor Stinner8c62be82010-05-06 00:08:46 +00006393 Py_BEGIN_ALLOW_THREADS
6394 n = readlink(path, buf, (int) sizeof buf);
6395 Py_END_ALLOW_THREADS
6396 if (n < 0)
6397 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00006398
Victor Stinner8c62be82010-05-06 00:08:46 +00006399 Py_DECREF(opath);
Victor Stinnera45598a2010-05-14 16:35:39 +00006400 if (arg_is_unicode)
6401 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
6402 else
6403 return PyBytes_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006404}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006405#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006406
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006407
Brian Curtin52173d42010-12-02 18:29:18 +00006408#if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006409PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006410"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006411Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006412
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006413static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006414posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006415{
Victor Stinner8c62be82010-05-06 00:08:46 +00006416 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006417}
6418#endif /* HAVE_SYMLINK */
6419
Brian Curtind40e6f72010-07-08 21:39:08 +00006420#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
6421
6422PyDoc_STRVAR(win_readlink__doc__,
6423"readlink(path) -> path\n\n\
6424Return a string representing the path to which the symbolic link points.");
6425
Brian Curtind40e6f72010-07-08 21:39:08 +00006426/* Windows readlink implementation */
6427static PyObject *
6428win_readlink(PyObject *self, PyObject *args)
6429{
6430 wchar_t *path;
6431 DWORD n_bytes_returned;
6432 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006433 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00006434 HANDLE reparse_point_handle;
6435
6436 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
6437 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
6438 wchar_t *print_name;
6439
6440 if (!PyArg_ParseTuple(args,
Victor Stinnereb5657a2011-09-30 01:44:27 +02006441 "U:readlink",
6442 &po))
6443 return NULL;
6444 path = PyUnicode_AsUnicode(po);
6445 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00006446 return NULL;
6447
6448 /* First get a handle to the reparse point */
6449 Py_BEGIN_ALLOW_THREADS
6450 reparse_point_handle = CreateFileW(
6451 path,
6452 0,
6453 0,
6454 0,
6455 OPEN_EXISTING,
6456 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
6457 0);
6458 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006459
Brian Curtind40e6f72010-07-08 21:39:08 +00006460 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006461 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006462
Brian Curtind40e6f72010-07-08 21:39:08 +00006463 Py_BEGIN_ALLOW_THREADS
6464 /* New call DeviceIoControl to read the reparse point */
6465 io_result = DeviceIoControl(
6466 reparse_point_handle,
6467 FSCTL_GET_REPARSE_POINT,
6468 0, 0, /* in buffer */
6469 target_buffer, sizeof(target_buffer),
6470 &n_bytes_returned,
6471 0 /* we're not using OVERLAPPED_IO */
6472 );
6473 CloseHandle(reparse_point_handle);
6474 Py_END_ALLOW_THREADS
6475
6476 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006477 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00006478
6479 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
6480 {
6481 PyErr_SetString(PyExc_ValueError,
6482 "not a symbolic link");
6483 return NULL;
6484 }
Brian Curtin74e45612010-07-09 15:58:59 +00006485 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
6486 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
6487
6488 result = PyUnicode_FromWideChar(print_name,
6489 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00006490 return result;
6491}
6492
6493#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
6494
Brian Curtin52173d42010-12-02 18:29:18 +00006495#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtind40e6f72010-07-08 21:39:08 +00006496
6497/* Grab CreateSymbolicLinkW dynamically from kernel32 */
6498static int has_CreateSymbolicLinkW = 0;
6499static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD);
6500static int
6501check_CreateSymbolicLinkW()
6502{
6503 HINSTANCE hKernel32;
6504 /* only recheck */
6505 if (has_CreateSymbolicLinkW)
6506 return has_CreateSymbolicLinkW;
Martin v. Löwis50590f12012-01-14 17:54:09 +01006507 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtin74e45612010-07-09 15:58:59 +00006508 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
6509 "CreateSymbolicLinkW");
Brian Curtind40e6f72010-07-08 21:39:08 +00006510 if (Py_CreateSymbolicLinkW)
6511 has_CreateSymbolicLinkW = 1;
6512 return has_CreateSymbolicLinkW;
6513}
6514
6515PyDoc_STRVAR(win_symlink__doc__,
6516"symlink(src, dst, target_is_directory=False)\n\n\
6517Create a symbolic link pointing to src named dst.\n\
6518target_is_directory is required if the target is to be interpreted as\n\
6519a directory.\n\
6520This function requires Windows 6.0 or greater, and raises a\n\
6521NotImplementedError otherwise.");
6522
6523static PyObject *
6524win_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
6525{
6526 static char *kwlist[] = {"src", "dest", "target_is_directory", NULL};
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006527 PyObject *osrc, *odest;
6528 PyObject *usrc = NULL, *udest = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006529 wchar_t *wsrc, *wdest;
Brian Curtind40e6f72010-07-08 21:39:08 +00006530 int target_is_directory = 0;
6531 DWORD res;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006532
Brian Curtind40e6f72010-07-08 21:39:08 +00006533 if (!check_CreateSymbolicLinkW())
6534 {
6535 /* raise NotImplementedError */
6536 return PyErr_Format(PyExc_NotImplementedError,
6537 "CreateSymbolicLinkW not found");
6538 }
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006539 if (!PyArg_ParseTupleAndKeywords(
6540 args, kwargs, "OO|i:symlink", kwlist,
6541 &osrc, &odest, &target_is_directory))
Brian Curtind40e6f72010-07-08 21:39:08 +00006542 return NULL;
Brian Curtin3b4499c2010-12-28 14:31:47 +00006543
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006544 usrc = win32_decode_filename(osrc);
6545 if (!usrc)
6546 return NULL;
6547 udest = win32_decode_filename(odest);
6548 if (!udest)
6549 goto error;
6550
Brian Curtin3b4499c2010-12-28 14:31:47 +00006551 if (win32_can_symlink == 0)
6552 return PyErr_Format(PyExc_OSError, "symbolic link privilege not held");
6553
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006554 wsrc = PyUnicode_AsUnicode(usrc);
Victor Stinnereb5657a2011-09-30 01:44:27 +02006555 if (wsrc == NULL)
6556 goto error;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006557 wdest = PyUnicode_AsUnicode(udest);
Victor Stinnereb5657a2011-09-30 01:44:27 +02006558 if (wsrc == NULL)
6559 goto error;
6560
Brian Curtind40e6f72010-07-08 21:39:08 +00006561 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006562 res = Py_CreateSymbolicLinkW(wdest, wsrc, target_is_directory);
Brian Curtind40e6f72010-07-08 21:39:08 +00006563 Py_END_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006564
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006565 Py_DECREF(usrc);
6566 Py_DECREF(udest);
Brian Curtind40e6f72010-07-08 21:39:08 +00006567 if (!res)
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006568 return win32_error_object("symlink", osrc);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006569
Brian Curtind40e6f72010-07-08 21:39:08 +00006570 Py_INCREF(Py_None);
6571 return Py_None;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006572
6573error:
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006574 Py_XDECREF(usrc);
6575 Py_XDECREF(udest);
Victor Stinnereb5657a2011-09-30 01:44:27 +02006576 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00006577}
Brian Curtin52173d42010-12-02 18:29:18 +00006578#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006579
6580#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006581#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6582static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006583system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006584{
6585 ULONG value = 0;
6586
6587 Py_BEGIN_ALLOW_THREADS
6588 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6589 Py_END_ALLOW_THREADS
6590
6591 return value;
6592}
6593
6594static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006595posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006596{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006597 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner8c62be82010-05-06 00:08:46 +00006598 return Py_BuildValue("ddddd",
6599 (double)0 /* t.tms_utime / HZ */,
6600 (double)0 /* t.tms_stime / HZ */,
6601 (double)0 /* t.tms_cutime / HZ */,
6602 (double)0 /* t.tms_cstime / HZ */,
6603 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006604}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006605#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00006606#define NEED_TICKS_PER_SECOND
6607static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006608static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006609posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006610{
Victor Stinner8c62be82010-05-06 00:08:46 +00006611 struct tms t;
6612 clock_t c;
6613 errno = 0;
6614 c = times(&t);
6615 if (c == (clock_t) -1)
6616 return posix_error();
6617 return Py_BuildValue("ddddd",
6618 (double)t.tms_utime / ticks_per_second,
6619 (double)t.tms_stime / ticks_per_second,
6620 (double)t.tms_cutime / ticks_per_second,
6621 (double)t.tms_cstime / ticks_per_second,
6622 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006623}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006624#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006625#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006626
6627
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006628#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006629#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006630static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006631posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006632{
Victor Stinner8c62be82010-05-06 00:08:46 +00006633 FILETIME create, exit, kernel, user;
6634 HANDLE hProc;
6635 hProc = GetCurrentProcess();
6636 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6637 /* The fields of a FILETIME structure are the hi and lo part
6638 of a 64-bit value expressed in 100 nanosecond units.
6639 1e7 is one second in such units; 1e-7 the inverse.
6640 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6641 */
6642 return Py_BuildValue(
6643 "ddddd",
6644 (double)(user.dwHighDateTime*429.4967296 +
6645 user.dwLowDateTime*1e-7),
6646 (double)(kernel.dwHighDateTime*429.4967296 +
6647 kernel.dwLowDateTime*1e-7),
6648 (double)0,
6649 (double)0,
6650 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006651}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006652#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006653
6654#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006655PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006656"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006657Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006658#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006659
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006660
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006661#ifdef HAVE_GETSID
6662PyDoc_STRVAR(posix_getsid__doc__,
6663"getsid(pid) -> sid\n\n\
6664Call the system call getsid().");
6665
6666static PyObject *
6667posix_getsid(PyObject *self, PyObject *args)
6668{
Victor Stinner8c62be82010-05-06 00:08:46 +00006669 pid_t pid;
6670 int sid;
6671 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
6672 return NULL;
6673 sid = getsid(pid);
6674 if (sid < 0)
6675 return posix_error();
6676 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006677}
6678#endif /* HAVE_GETSID */
6679
6680
Guido van Rossumb6775db1994-08-01 11:34:53 +00006681#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006682PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006683"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006684Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006685
Barry Warsaw53699e91996-12-10 23:23:01 +00006686static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006687posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006688{
Victor Stinner8c62be82010-05-06 00:08:46 +00006689 if (setsid() < 0)
6690 return posix_error();
6691 Py_INCREF(Py_None);
6692 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006693}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006694#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006695
Guido van Rossumb6775db1994-08-01 11:34:53 +00006696#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006697PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006698"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006699Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006700
Barry Warsaw53699e91996-12-10 23:23:01 +00006701static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006702posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006703{
Victor Stinner8c62be82010-05-06 00:08:46 +00006704 pid_t pid;
6705 int pgrp;
6706 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
6707 return NULL;
6708 if (setpgid(pid, pgrp) < 0)
6709 return posix_error();
6710 Py_INCREF(Py_None);
6711 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006712}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006713#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006714
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006715
Guido van Rossumb6775db1994-08-01 11:34:53 +00006716#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006717PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006718"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006719Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006720
Barry Warsaw53699e91996-12-10 23:23:01 +00006721static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006722posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006723{
Victor Stinner8c62be82010-05-06 00:08:46 +00006724 int fd;
6725 pid_t pgid;
6726 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6727 return NULL;
6728 pgid = tcgetpgrp(fd);
6729 if (pgid < 0)
6730 return posix_error();
6731 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006732}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006733#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006734
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006735
Guido van Rossumb6775db1994-08-01 11:34:53 +00006736#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006737PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006738"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006739Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006740
Barry Warsaw53699e91996-12-10 23:23:01 +00006741static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006742posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006743{
Victor Stinner8c62be82010-05-06 00:08:46 +00006744 int fd;
6745 pid_t pgid;
6746 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
6747 return NULL;
6748 if (tcsetpgrp(fd, pgid) < 0)
6749 return posix_error();
6750 Py_INCREF(Py_None);
6751 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006752}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006753#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006754
Guido van Rossum687dd131993-05-17 08:34:16 +00006755/* Functions acting on file descriptors */
6756
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006757PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006758"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006759Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006760
Barry Warsaw53699e91996-12-10 23:23:01 +00006761static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006762posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006763{
Victor Stinner8c62be82010-05-06 00:08:46 +00006764 PyObject *ofile;
6765 char *file;
6766 int flag;
6767 int mode = 0777;
6768 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006769
6770#ifdef MS_WINDOWS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006771 PyObject *po;
Victor Stinner26de69d2011-06-17 15:15:38 +02006772 if (PyArg_ParseTuple(args, "Ui|i:open", &po, &flag, &mode)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02006773 wchar_t *wpath = PyUnicode_AsUnicode(po);
6774 if (wpath == NULL)
6775 return NULL;
6776
Victor Stinner8c62be82010-05-06 00:08:46 +00006777 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006778 fd = _wopen(wpath, flag, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00006779 Py_END_ALLOW_THREADS
6780 if (fd < 0)
6781 return posix_error();
6782 return PyLong_FromLong((long)fd);
6783 }
6784 /* Drop the argument parsing error as narrow strings
6785 are also valid. */
6786 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006787#endif
6788
Victor Stinner26de69d2011-06-17 15:15:38 +02006789 if (!PyArg_ParseTuple(args, "O&i|i:open",
Victor Stinner8c62be82010-05-06 00:08:46 +00006790 PyUnicode_FSConverter, &ofile,
6791 &flag, &mode))
6792 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006793#ifdef MS_WINDOWS
6794 if (win32_warn_bytes_api()) {
6795 Py_DECREF(ofile);
6796 return NULL;
6797 }
6798#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006799 file = PyBytes_AsString(ofile);
6800 Py_BEGIN_ALLOW_THREADS
6801 fd = open(file, flag, mode);
6802 Py_END_ALLOW_THREADS
6803 if (fd < 0)
6804 return posix_error_with_allocated_filename(ofile);
6805 Py_DECREF(ofile);
6806 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006807}
6808
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006809
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006810PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006811"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006812Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006813
Barry Warsaw53699e91996-12-10 23:23:01 +00006814static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006815posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006816{
Victor Stinner8c62be82010-05-06 00:08:46 +00006817 int fd, res;
6818 if (!PyArg_ParseTuple(args, "i:close", &fd))
6819 return NULL;
6820 if (!_PyVerify_fd(fd))
6821 return posix_error();
6822 Py_BEGIN_ALLOW_THREADS
6823 res = close(fd);
6824 Py_END_ALLOW_THREADS
6825 if (res < 0)
6826 return posix_error();
6827 Py_INCREF(Py_None);
6828 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006829}
6830
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006831
Victor Stinner8c62be82010-05-06 00:08:46 +00006832PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00006833"closerange(fd_low, fd_high)\n\n\
6834Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6835
6836static PyObject *
6837posix_closerange(PyObject *self, PyObject *args)
6838{
Victor Stinner8c62be82010-05-06 00:08:46 +00006839 int fd_from, fd_to, i;
6840 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6841 return NULL;
6842 Py_BEGIN_ALLOW_THREADS
6843 for (i = fd_from; i < fd_to; i++)
6844 if (_PyVerify_fd(i))
6845 close(i);
6846 Py_END_ALLOW_THREADS
6847 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00006848}
6849
6850
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006851PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006852"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006853Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006854
Barry Warsaw53699e91996-12-10 23:23:01 +00006855static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006856posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006857{
Victor Stinner8c62be82010-05-06 00:08:46 +00006858 int fd;
6859 if (!PyArg_ParseTuple(args, "i:dup", &fd))
6860 return NULL;
6861 if (!_PyVerify_fd(fd))
6862 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006863 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00006864 if (fd < 0)
6865 return posix_error();
6866 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006867}
6868
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006869
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006870PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006871"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006872Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006873
Barry Warsaw53699e91996-12-10 23:23:01 +00006874static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006875posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006876{
Victor Stinner8c62be82010-05-06 00:08:46 +00006877 int fd, fd2, res;
6878 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
6879 return NULL;
6880 if (!_PyVerify_fd_dup2(fd, fd2))
6881 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006882 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00006883 if (res < 0)
6884 return posix_error();
6885 Py_INCREF(Py_None);
6886 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006887}
6888
Ross Lagerwall7807c352011-03-17 20:20:30 +02006889#ifdef HAVE_LOCKF
6890PyDoc_STRVAR(posix_lockf__doc__,
6891"lockf(fd, cmd, len)\n\n\
6892Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
6893fd is an open file descriptor.\n\
6894cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
6895F_TEST.\n\
6896len specifies the section of the file to lock.");
6897
6898static PyObject *
6899posix_lockf(PyObject *self, PyObject *args)
6900{
6901 int fd, cmd, res;
6902 off_t len;
6903 if (!PyArg_ParseTuple(args, "iiO&:lockf",
6904 &fd, &cmd, _parse_off_t, &len))
6905 return NULL;
6906
6907 Py_BEGIN_ALLOW_THREADS
6908 res = lockf(fd, cmd, len);
6909 Py_END_ALLOW_THREADS
6910
6911 if (res < 0)
6912 return posix_error();
6913
6914 Py_RETURN_NONE;
6915}
6916#endif
6917
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006918
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006919PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006920"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01006921Set the current position of a file descriptor.\n\
6922Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006923
Barry Warsaw53699e91996-12-10 23:23:01 +00006924static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006925posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006926{
Victor Stinner8c62be82010-05-06 00:08:46 +00006927 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006928#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00006929 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006930#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006931 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006932#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02006933 PyObject *posobj;
6934 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00006935 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006936#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00006937 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6938 switch (how) {
6939 case 0: how = SEEK_SET; break;
6940 case 1: how = SEEK_CUR; break;
6941 case 2: how = SEEK_END; break;
6942 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006943#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006944
Ross Lagerwall8e749672011-03-17 21:54:07 +02006945#if !defined(HAVE_LARGEFILE_SUPPORT)
6946 pos = PyLong_AsLong(posobj);
6947#else
6948 pos = PyLong_AsLongLong(posobj);
6949#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006950 if (PyErr_Occurred())
6951 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006952
Victor Stinner8c62be82010-05-06 00:08:46 +00006953 if (!_PyVerify_fd(fd))
6954 return posix_error();
6955 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006956#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00006957 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006958#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006959 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006960#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006961 Py_END_ALLOW_THREADS
6962 if (res < 0)
6963 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006964
6965#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00006966 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006967#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006968 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006969#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006970}
6971
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006972
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006973PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006974"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006975Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006976
Barry Warsaw53699e91996-12-10 23:23:01 +00006977static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006978posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006979{
Victor Stinner8c62be82010-05-06 00:08:46 +00006980 int fd, size;
6981 Py_ssize_t n;
6982 PyObject *buffer;
6983 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
6984 return NULL;
6985 if (size < 0) {
6986 errno = EINVAL;
6987 return posix_error();
6988 }
6989 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
6990 if (buffer == NULL)
6991 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00006992 if (!_PyVerify_fd(fd)) {
6993 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00006994 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00006995 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006996 Py_BEGIN_ALLOW_THREADS
6997 n = read(fd, PyBytes_AS_STRING(buffer), size);
6998 Py_END_ALLOW_THREADS
6999 if (n < 0) {
7000 Py_DECREF(buffer);
7001 return posix_error();
7002 }
7003 if (n != size)
7004 _PyBytes_Resize(&buffer, n);
7005 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007006}
7007
Ross Lagerwall7807c352011-03-17 20:20:30 +02007008#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7009 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007010static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007011iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7012{
7013 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007014 Py_ssize_t blen, total = 0;
7015
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007016 *iov = PyMem_New(struct iovec, cnt);
7017 if (*iov == NULL) {
7018 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007019 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007020 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007021
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007022 *buf = PyMem_New(Py_buffer, cnt);
7023 if (*buf == NULL) {
7024 PyMem_Del(*iov);
7025 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007026 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007027 }
7028
7029 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007030 PyObject *item = PySequence_GetItem(seq, i);
7031 if (item == NULL)
7032 goto fail;
7033 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7034 Py_DECREF(item);
7035 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007036 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007037 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007038 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007039 blen = (*buf)[i].len;
7040 (*iov)[i].iov_len = blen;
7041 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007042 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007043 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007044
7045fail:
7046 PyMem_Del(*iov);
7047 for (j = 0; j < i; j++) {
7048 PyBuffer_Release(&(*buf)[j]);
7049 }
7050 PyMem_Del(*buf);
7051 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007052}
7053
7054static void
7055iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7056{
7057 int i;
7058 PyMem_Del(iov);
7059 for (i = 0; i < cnt; i++) {
7060 PyBuffer_Release(&buf[i]);
7061 }
7062 PyMem_Del(buf);
7063}
7064#endif
7065
Ross Lagerwall7807c352011-03-17 20:20:30 +02007066#ifdef HAVE_READV
7067PyDoc_STRVAR(posix_readv__doc__,
7068"readv(fd, buffers) -> bytesread\n\n\
7069Read from a file descriptor into a number of writable buffers. buffers\n\
7070is an arbitrary sequence of writable buffers.\n\
7071Returns the total number of bytes read.");
7072
7073static PyObject *
7074posix_readv(PyObject *self, PyObject *args)
7075{
7076 int fd, cnt;
7077 Py_ssize_t n;
7078 PyObject *seq;
7079 struct iovec *iov;
7080 Py_buffer *buf;
7081
7082 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7083 return NULL;
7084 if (!PySequence_Check(seq)) {
7085 PyErr_SetString(PyExc_TypeError,
7086 "readv() arg 2 must be a sequence");
7087 return NULL;
7088 }
7089 cnt = PySequence_Size(seq);
7090
7091 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7092 return NULL;
7093
7094 Py_BEGIN_ALLOW_THREADS
7095 n = readv(fd, iov, cnt);
7096 Py_END_ALLOW_THREADS
7097
7098 iov_cleanup(iov, buf, cnt);
7099 return PyLong_FromSsize_t(n);
7100}
7101#endif
7102
7103#ifdef HAVE_PREAD
7104PyDoc_STRVAR(posix_pread__doc__,
7105"pread(fd, buffersize, offset) -> string\n\n\
7106Read from a file descriptor, fd, at a position of offset. It will read up\n\
7107to buffersize number of bytes. The file offset remains unchanged.");
7108
7109static PyObject *
7110posix_pread(PyObject *self, PyObject *args)
7111{
7112 int fd, size;
7113 off_t offset;
7114 Py_ssize_t n;
7115 PyObject *buffer;
7116 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7117 return NULL;
7118
7119 if (size < 0) {
7120 errno = EINVAL;
7121 return posix_error();
7122 }
7123 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7124 if (buffer == NULL)
7125 return NULL;
7126 if (!_PyVerify_fd(fd)) {
7127 Py_DECREF(buffer);
7128 return posix_error();
7129 }
7130 Py_BEGIN_ALLOW_THREADS
7131 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7132 Py_END_ALLOW_THREADS
7133 if (n < 0) {
7134 Py_DECREF(buffer);
7135 return posix_error();
7136 }
7137 if (n != size)
7138 _PyBytes_Resize(&buffer, n);
7139 return buffer;
7140}
7141#endif
7142
7143PyDoc_STRVAR(posix_write__doc__,
7144"write(fd, string) -> byteswritten\n\n\
7145Write a string to a file descriptor.");
7146
7147static PyObject *
7148posix_write(PyObject *self, PyObject *args)
7149{
7150 Py_buffer pbuf;
7151 int fd;
7152 Py_ssize_t size, len;
7153
7154 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
7155 return NULL;
7156 if (!_PyVerify_fd(fd)) {
7157 PyBuffer_Release(&pbuf);
7158 return posix_error();
7159 }
7160 len = pbuf.len;
7161 Py_BEGIN_ALLOW_THREADS
7162#if defined(MS_WIN64) || defined(MS_WINDOWS)
7163 if (len > INT_MAX)
7164 len = INT_MAX;
7165 size = write(fd, pbuf.buf, (int)len);
7166#else
7167 size = write(fd, pbuf.buf, len);
7168#endif
7169 Py_END_ALLOW_THREADS
7170 PyBuffer_Release(&pbuf);
7171 if (size < 0)
7172 return posix_error();
7173 return PyLong_FromSsize_t(size);
7174}
7175
7176#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007177PyDoc_STRVAR(posix_sendfile__doc__,
7178"sendfile(out, in, offset, nbytes) -> byteswritten\n\
7179sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
7180 -> byteswritten\n\
7181Copy nbytes bytes from file descriptor in to file descriptor out.");
7182
7183static PyObject *
7184posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
7185{
7186 int in, out;
7187 Py_ssize_t ret;
7188 off_t offset;
7189
7190#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
7191#ifndef __APPLE__
7192 Py_ssize_t len;
7193#endif
7194 PyObject *headers = NULL, *trailers = NULL;
7195 Py_buffer *hbuf, *tbuf;
7196 off_t sbytes;
7197 struct sf_hdtr sf;
7198 int flags = 0;
7199 sf.headers = NULL;
7200 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00007201 static char *keywords[] = {"out", "in",
7202 "offset", "count",
7203 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007204
7205#ifdef __APPLE__
7206 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007207 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007208#else
7209 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007210 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007211#endif
7212 &headers, &trailers, &flags))
7213 return NULL;
7214 if (headers != NULL) {
7215 if (!PySequence_Check(headers)) {
7216 PyErr_SetString(PyExc_TypeError,
7217 "sendfile() headers must be a sequence or None");
7218 return NULL;
7219 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007220 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007221 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007222 if (sf.hdr_cnt > 0 &&
7223 !(i = iov_setup(&(sf.headers), &hbuf,
7224 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007225 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007226#ifdef __APPLE__
7227 sbytes += i;
7228#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007229 }
7230 }
7231 if (trailers != NULL) {
7232 if (!PySequence_Check(trailers)) {
7233 PyErr_SetString(PyExc_TypeError,
7234 "sendfile() trailers must be a sequence or None");
7235 return NULL;
7236 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007237 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007238 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007239 if (sf.trl_cnt > 0 &&
7240 !(i = iov_setup(&(sf.trailers), &tbuf,
7241 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007242 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007243#ifdef __APPLE__
7244 sbytes += i;
7245#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007246 }
7247 }
7248
7249 Py_BEGIN_ALLOW_THREADS
7250#ifdef __APPLE__
7251 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
7252#else
7253 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
7254#endif
7255 Py_END_ALLOW_THREADS
7256
7257 if (sf.headers != NULL)
7258 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
7259 if (sf.trailers != NULL)
7260 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
7261
7262 if (ret < 0) {
7263 if ((errno == EAGAIN) || (errno == EBUSY)) {
7264 if (sbytes != 0) {
7265 // some data has been sent
7266 goto done;
7267 }
7268 else {
7269 // no data has been sent; upper application is supposed
7270 // to retry on EAGAIN or EBUSY
7271 return posix_error();
7272 }
7273 }
7274 return posix_error();
7275 }
7276 goto done;
7277
7278done:
7279 #if !defined(HAVE_LARGEFILE_SUPPORT)
7280 return Py_BuildValue("l", sbytes);
7281 #else
7282 return Py_BuildValue("L", sbytes);
7283 #endif
7284
7285#else
7286 Py_ssize_t count;
7287 PyObject *offobj;
7288 static char *keywords[] = {"out", "in",
7289 "offset", "count", NULL};
7290 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
7291 keywords, &out, &in, &offobj, &count))
7292 return NULL;
7293#ifdef linux
7294 if (offobj == Py_None) {
7295 Py_BEGIN_ALLOW_THREADS
7296 ret = sendfile(out, in, NULL, count);
7297 Py_END_ALLOW_THREADS
7298 if (ret < 0)
7299 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02007300 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007301 }
7302#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00007303 if (!_parse_off_t(offobj, &offset))
7304 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007305 Py_BEGIN_ALLOW_THREADS
7306 ret = sendfile(out, in, &offset, count);
7307 Py_END_ALLOW_THREADS
7308 if (ret < 0)
7309 return posix_error();
7310 return Py_BuildValue("n", ret);
7311#endif
7312}
7313#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007314
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007315PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007316"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007317Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007318
Barry Warsaw53699e91996-12-10 23:23:01 +00007319static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007320posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007321{
Victor Stinner8c62be82010-05-06 00:08:46 +00007322 int fd;
7323 STRUCT_STAT st;
7324 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01007325 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007326 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007327#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00007328 /* on OpenVMS we must ensure that all bytes are written to the file */
7329 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007330#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007331 if (!_PyVerify_fd(fd))
7332 return posix_error();
7333 Py_BEGIN_ALLOW_THREADS
7334 res = FSTAT(fd, &st);
7335 Py_END_ALLOW_THREADS
7336 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00007337#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007338 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00007339#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007340 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00007341#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007342 }
Tim Peters5aa91602002-01-30 05:46:57 +00007343
Victor Stinner4195b5c2012-02-08 23:03:19 +01007344 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00007345}
7346
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007347PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007348"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007349Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007350connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00007351
7352static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00007353posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00007354{
Victor Stinner8c62be82010-05-06 00:08:46 +00007355 int fd;
7356 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
7357 return NULL;
7358 if (!_PyVerify_fd(fd))
7359 return PyBool_FromLong(0);
7360 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00007361}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007362
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007363#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007364PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007365"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007366Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007367
Barry Warsaw53699e91996-12-10 23:23:01 +00007368static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007369posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007370{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007371#if defined(PYOS_OS2)
7372 HFILE read, write;
7373 APIRET rc;
7374
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007375 rc = DosCreatePipe( &read, &write, 4096);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007376 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007377 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007378
7379 return Py_BuildValue("(ii)", read, write);
7380#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007381#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007382 int fds[2];
7383 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007384 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00007385 if (res != 0)
7386 return posix_error();
7387 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007388#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007389 HANDLE read, write;
7390 int read_fd, write_fd;
7391 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00007392 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00007393 if (!ok)
7394 return win32_error("CreatePipe", NULL);
7395 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
7396 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
7397 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007398#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007399#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007400}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007401#endif /* HAVE_PIPE */
7402
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007403#ifdef HAVE_PIPE2
7404PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02007405"pipe2(flags) -> (read_end, write_end)\n\n\
7406Create a pipe with flags set atomically.\n\
7407flags can be constructed by ORing together one or more of these values:\n\
7408O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007409");
7410
7411static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02007412posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007413{
Charles-François Natali368f34b2011-06-06 19:49:47 +02007414 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007415 int fds[2];
7416 int res;
7417
Charles-François Natali368f34b2011-06-06 19:49:47 +02007418 flags = PyLong_AsLong(arg);
7419 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007420 return NULL;
7421
7422 res = pipe2(fds, flags);
7423 if (res != 0)
7424 return posix_error();
7425 return Py_BuildValue("(ii)", fds[0], fds[1]);
7426}
7427#endif /* HAVE_PIPE2 */
7428
Ross Lagerwall7807c352011-03-17 20:20:30 +02007429#ifdef HAVE_WRITEV
7430PyDoc_STRVAR(posix_writev__doc__,
7431"writev(fd, buffers) -> byteswritten\n\n\
7432Write the contents of buffers to a file descriptor, where buffers is an\n\
7433arbitrary sequence of buffers.\n\
7434Returns the total bytes written.");
7435
7436static PyObject *
7437posix_writev(PyObject *self, PyObject *args)
7438{
7439 int fd, cnt;
7440 Py_ssize_t res;
7441 PyObject *seq;
7442 struct iovec *iov;
7443 Py_buffer *buf;
7444 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
7445 return NULL;
7446 if (!PySequence_Check(seq)) {
7447 PyErr_SetString(PyExc_TypeError,
7448 "writev() arg 2 must be a sequence");
7449 return NULL;
7450 }
7451 cnt = PySequence_Size(seq);
7452
7453 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
7454 return NULL;
7455 }
7456
7457 Py_BEGIN_ALLOW_THREADS
7458 res = writev(fd, iov, cnt);
7459 Py_END_ALLOW_THREADS
7460
7461 iov_cleanup(iov, buf, cnt);
7462 return PyLong_FromSsize_t(res);
7463}
7464#endif
7465
7466#ifdef HAVE_PWRITE
7467PyDoc_STRVAR(posix_pwrite__doc__,
7468"pwrite(fd, string, offset) -> byteswritten\n\n\
7469Write string to a file descriptor, fd, from offset, leaving the file\n\
7470offset unchanged.");
7471
7472static PyObject *
7473posix_pwrite(PyObject *self, PyObject *args)
7474{
7475 Py_buffer pbuf;
7476 int fd;
7477 off_t offset;
7478 Py_ssize_t size;
7479
7480 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
7481 return NULL;
7482
7483 if (!_PyVerify_fd(fd)) {
7484 PyBuffer_Release(&pbuf);
7485 return posix_error();
7486 }
7487 Py_BEGIN_ALLOW_THREADS
7488 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
7489 Py_END_ALLOW_THREADS
7490 PyBuffer_Release(&pbuf);
7491 if (size < 0)
7492 return posix_error();
7493 return PyLong_FromSsize_t(size);
7494}
7495#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007496
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007497#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007498PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007499"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007500Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007501
Barry Warsaw53699e91996-12-10 23:23:01 +00007502static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007503posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007504{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007505 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00007506 char *filename;
7507 int mode = 0666;
7508 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007509 if (!PyArg_ParseTuple(args, "O&|i:mkfifo", PyUnicode_FSConverter, &opath,
7510 &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00007511 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007512 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007513 Py_BEGIN_ALLOW_THREADS
7514 res = mkfifo(filename, mode);
7515 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007516 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007517 if (res < 0)
7518 return posix_error();
7519 Py_INCREF(Py_None);
7520 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007521}
7522#endif
7523
7524
Neal Norwitz11690112002-07-30 01:08:28 +00007525#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007526PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007527"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007528Create a filesystem node (file, device special file or named pipe)\n\
7529named filename. mode specifies both the permissions to use and the\n\
7530type of node to be created, being combined (bitwise OR) with one of\n\
7531S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007532device defines the newly created device special file (probably using\n\
7533os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007534
7535
7536static PyObject *
7537posix_mknod(PyObject *self, PyObject *args)
7538{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007539 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00007540 char *filename;
7541 int mode = 0600;
7542 int device = 0;
7543 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007544 if (!PyArg_ParseTuple(args, "O&|ii:mknod", PyUnicode_FSConverter, &opath,
7545 &mode, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00007546 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007547 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007548 Py_BEGIN_ALLOW_THREADS
7549 res = mknod(filename, mode, device);
7550 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007551 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007552 if (res < 0)
7553 return posix_error();
7554 Py_INCREF(Py_None);
7555 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007556}
7557#endif
7558
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007559#ifdef HAVE_DEVICE_MACROS
7560PyDoc_STRVAR(posix_major__doc__,
7561"major(device) -> major number\n\
7562Extracts a device major number from a raw device number.");
7563
7564static PyObject *
7565posix_major(PyObject *self, PyObject *args)
7566{
Victor Stinner8c62be82010-05-06 00:08:46 +00007567 int device;
7568 if (!PyArg_ParseTuple(args, "i:major", &device))
7569 return NULL;
7570 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007571}
7572
7573PyDoc_STRVAR(posix_minor__doc__,
7574"minor(device) -> minor number\n\
7575Extracts a device minor number from a raw device number.");
7576
7577static PyObject *
7578posix_minor(PyObject *self, PyObject *args)
7579{
Victor Stinner8c62be82010-05-06 00:08:46 +00007580 int device;
7581 if (!PyArg_ParseTuple(args, "i:minor", &device))
7582 return NULL;
7583 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007584}
7585
7586PyDoc_STRVAR(posix_makedev__doc__,
7587"makedev(major, minor) -> device number\n\
7588Composes a raw device number from the major and minor device numbers.");
7589
7590static PyObject *
7591posix_makedev(PyObject *self, PyObject *args)
7592{
Victor Stinner8c62be82010-05-06 00:08:46 +00007593 int major, minor;
7594 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
7595 return NULL;
7596 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007597}
7598#endif /* device macros */
7599
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007600
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007601#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007602PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007603"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007604Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007605
Barry Warsaw53699e91996-12-10 23:23:01 +00007606static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007607posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007608{
Victor Stinner8c62be82010-05-06 00:08:46 +00007609 int fd;
7610 off_t length;
7611 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007612
Ross Lagerwall7807c352011-03-17 20:20:30 +02007613 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00007614 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007615
Victor Stinner8c62be82010-05-06 00:08:46 +00007616 Py_BEGIN_ALLOW_THREADS
7617 res = ftruncate(fd, length);
7618 Py_END_ALLOW_THREADS
7619 if (res < 0)
7620 return posix_error();
7621 Py_INCREF(Py_None);
7622 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007623}
7624#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007625
Ross Lagerwall7807c352011-03-17 20:20:30 +02007626#ifdef HAVE_TRUNCATE
7627PyDoc_STRVAR(posix_truncate__doc__,
7628"truncate(path, length)\n\n\
7629Truncate the file given by path to length bytes.");
7630
7631static PyObject *
7632posix_truncate(PyObject *self, PyObject *args)
7633{
7634 PyObject *opath;
7635 const char *path;
7636 off_t length;
7637 int res;
7638
7639 if (!PyArg_ParseTuple(args, "O&O&:truncate",
7640 PyUnicode_FSConverter, &opath, _parse_off_t, &length))
7641 return NULL;
7642 path = PyBytes_AsString(opath);
7643
7644 Py_BEGIN_ALLOW_THREADS
7645 res = truncate(path, length);
7646 Py_END_ALLOW_THREADS
7647 Py_DECREF(opath);
7648 if (res < 0)
7649 return posix_error();
7650 Py_RETURN_NONE;
7651}
7652#endif
7653
7654#ifdef HAVE_POSIX_FALLOCATE
7655PyDoc_STRVAR(posix_posix_fallocate__doc__,
7656"posix_fallocate(fd, offset, len)\n\n\
7657Ensures that enough disk space is allocated for the file specified by fd\n\
7658starting from offset and continuing for len bytes.");
7659
7660static PyObject *
7661posix_posix_fallocate(PyObject *self, PyObject *args)
7662{
7663 off_t len, offset;
7664 int res, fd;
7665
7666 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
7667 &fd, _parse_off_t, &offset, _parse_off_t, &len))
7668 return NULL;
7669
7670 Py_BEGIN_ALLOW_THREADS
7671 res = posix_fallocate(fd, offset, len);
7672 Py_END_ALLOW_THREADS
7673 if (res != 0) {
7674 errno = res;
7675 return posix_error();
7676 }
7677 Py_RETURN_NONE;
7678}
7679#endif
7680
7681#ifdef HAVE_POSIX_FADVISE
7682PyDoc_STRVAR(posix_posix_fadvise__doc__,
7683"posix_fadvise(fd, offset, len, advice)\n\n\
7684Announces an intention to access data in a specific pattern thus allowing\n\
7685the kernel to make optimizations.\n\
7686The advice applies to the region of the file specified by fd starting at\n\
7687offset and continuing for len bytes.\n\
7688advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
7689POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
7690POSIX_FADV_DONTNEED.");
7691
7692static PyObject *
7693posix_posix_fadvise(PyObject *self, PyObject *args)
7694{
7695 off_t len, offset;
7696 int res, fd, advice;
7697
7698 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
7699 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
7700 return NULL;
7701
7702 Py_BEGIN_ALLOW_THREADS
7703 res = posix_fadvise(fd, offset, len, advice);
7704 Py_END_ALLOW_THREADS
7705 if (res != 0) {
7706 errno = res;
7707 return posix_error();
7708 }
7709 Py_RETURN_NONE;
7710}
7711#endif
7712
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007713#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007714PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007715"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007716Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007717
Fred Drake762e2061999-08-26 17:23:54 +00007718/* Save putenv() parameters as values here, so we can collect them when they
7719 * get re-set with another call for the same key. */
7720static PyObject *posix_putenv_garbage;
7721
Tim Peters5aa91602002-01-30 05:46:57 +00007722static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007723posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007724{
Victor Stinner84ae1182010-05-06 22:05:07 +00007725 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007726#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01007727 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007728 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01007729
Victor Stinner8c62be82010-05-06 00:08:46 +00007730 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01007731 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01007732 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00007733 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007734
Victor Stinner65170952011-11-22 22:16:17 +01007735 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00007736 if (newstr == NULL) {
7737 PyErr_NoMemory();
7738 goto error;
7739 }
Victor Stinner65170952011-11-22 22:16:17 +01007740 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
7741 PyErr_Format(PyExc_ValueError,
7742 "the environment variable is longer than %u characters",
7743 _MAX_ENV);
7744 goto error;
7745 }
7746
Victor Stinner8c62be82010-05-06 00:08:46 +00007747 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02007748 if (newenv == NULL)
7749 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007750 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007751 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00007752 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007753 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007754#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007755 PyObject *os1, *os2;
7756 char *s1, *s2;
7757 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007758
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007759 if (!PyArg_ParseTuple(args,
7760 "O&O&:putenv",
7761 PyUnicode_FSConverter, &os1,
7762 PyUnicode_FSConverter, &os2))
7763 return NULL;
7764 s1 = PyBytes_AsString(os1);
7765 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00007766
Victor Stinner65170952011-11-22 22:16:17 +01007767 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01007768 if (newstr == NULL) {
7769 PyErr_NoMemory();
7770 goto error;
7771 }
7772
Victor Stinner8c62be82010-05-06 00:08:46 +00007773 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00007774 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007775 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00007776 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007777 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007778#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007779
Victor Stinner8c62be82010-05-06 00:08:46 +00007780 /* Install the first arg and newstr in posix_putenv_garbage;
7781 * this will cause previous value to be collected. This has to
7782 * happen after the real putenv() call because the old value
7783 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01007784 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007785 /* really not much we can do; just leak */
7786 PyErr_Clear();
7787 }
7788 else {
7789 Py_DECREF(newstr);
7790 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00007791
Martin v. Löwis011e8422009-05-05 04:43:17 +00007792#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007793 Py_DECREF(os1);
7794 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00007795#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007796 Py_RETURN_NONE;
7797
7798error:
7799#ifndef MS_WINDOWS
7800 Py_DECREF(os1);
7801 Py_DECREF(os2);
7802#endif
7803 Py_XDECREF(newstr);
7804 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00007805}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007806#endif /* putenv */
7807
Guido van Rossumc524d952001-10-19 01:31:59 +00007808#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007809PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007810"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007811Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00007812
7813static PyObject *
7814posix_unsetenv(PyObject *self, PyObject *args)
7815{
Victor Stinner65170952011-11-22 22:16:17 +01007816 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01007817#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01007818 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01007819#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007820
7821 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00007822
Victor Stinner65170952011-11-22 22:16:17 +01007823 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00007824 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00007825
Victor Stinner984890f2011-11-24 13:53:38 +01007826#ifdef HAVE_BROKEN_UNSETENV
7827 unsetenv(PyBytes_AS_STRING(name));
7828#else
Victor Stinner65170952011-11-22 22:16:17 +01007829 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06007830 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06007831 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01007832 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06007833 }
Victor Stinner984890f2011-11-24 13:53:38 +01007834#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007835
Victor Stinner8c62be82010-05-06 00:08:46 +00007836 /* Remove the key from posix_putenv_garbage;
7837 * this will cause it to be collected. This has to
7838 * happen after the real unsetenv() call because the
7839 * old value was still accessible until then.
7840 */
Victor Stinner65170952011-11-22 22:16:17 +01007841 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007842 /* really not much we can do; just leak */
7843 PyErr_Clear();
7844 }
Victor Stinner65170952011-11-22 22:16:17 +01007845 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00007846 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00007847}
7848#endif /* unsetenv */
7849
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007850PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007851"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007852Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00007853
Guido van Rossumf68d8e52001-04-14 17:55:09 +00007854static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007855posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00007856{
Victor Stinner8c62be82010-05-06 00:08:46 +00007857 int code;
7858 char *message;
7859 if (!PyArg_ParseTuple(args, "i:strerror", &code))
7860 return NULL;
7861 message = strerror(code);
7862 if (message == NULL) {
7863 PyErr_SetString(PyExc_ValueError,
7864 "strerror() argument out of range");
7865 return NULL;
7866 }
Victor Stinner1b579672011-12-17 05:47:23 +01007867 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00007868}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007869
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007870
Guido van Rossumc9641791998-08-04 15:26:23 +00007871#ifdef HAVE_SYS_WAIT_H
7872
Fred Drake106c1a02002-04-23 15:58:02 +00007873#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007874PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007875"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007876Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00007877
7878static PyObject *
7879posix_WCOREDUMP(PyObject *self, PyObject *args)
7880{
Victor Stinner8c62be82010-05-06 00:08:46 +00007881 WAIT_TYPE status;
7882 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007883
Victor Stinner8c62be82010-05-06 00:08:46 +00007884 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
7885 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007886
Victor Stinner8c62be82010-05-06 00:08:46 +00007887 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007888}
7889#endif /* WCOREDUMP */
7890
7891#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007892PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007893"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007894Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007895job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00007896
7897static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007898posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00007899{
Victor Stinner8c62be82010-05-06 00:08:46 +00007900 WAIT_TYPE status;
7901 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007902
Victor Stinner8c62be82010-05-06 00:08:46 +00007903 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
7904 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007905
Victor Stinner8c62be82010-05-06 00:08:46 +00007906 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007907}
7908#endif /* WIFCONTINUED */
7909
Guido van Rossumc9641791998-08-04 15:26:23 +00007910#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007911PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007912"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007913Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007914
7915static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007916posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007917{
Victor Stinner8c62be82010-05-06 00:08:46 +00007918 WAIT_TYPE status;
7919 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007920
Victor Stinner8c62be82010-05-06 00:08:46 +00007921 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
7922 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007923
Victor Stinner8c62be82010-05-06 00:08:46 +00007924 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007925}
7926#endif /* WIFSTOPPED */
7927
7928#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007929PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007930"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007931Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007932
7933static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007934posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007935{
Victor Stinner8c62be82010-05-06 00:08:46 +00007936 WAIT_TYPE status;
7937 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007938
Victor Stinner8c62be82010-05-06 00:08:46 +00007939 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
7940 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007941
Victor Stinner8c62be82010-05-06 00:08:46 +00007942 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007943}
7944#endif /* WIFSIGNALED */
7945
7946#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007947PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007948"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007949Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007950system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007951
7952static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007953posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007954{
Victor Stinner8c62be82010-05-06 00:08:46 +00007955 WAIT_TYPE status;
7956 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007957
Victor Stinner8c62be82010-05-06 00:08:46 +00007958 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
7959 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007960
Victor Stinner8c62be82010-05-06 00:08:46 +00007961 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007962}
7963#endif /* WIFEXITED */
7964
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007965#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007966PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007967"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007968Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007969
7970static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007971posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007972{
Victor Stinner8c62be82010-05-06 00:08:46 +00007973 WAIT_TYPE status;
7974 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007975
Victor Stinner8c62be82010-05-06 00:08:46 +00007976 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
7977 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007978
Victor Stinner8c62be82010-05-06 00:08:46 +00007979 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007980}
7981#endif /* WEXITSTATUS */
7982
7983#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007984PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007985"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007986Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007987value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007988
7989static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007990posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007991{
Victor Stinner8c62be82010-05-06 00:08:46 +00007992 WAIT_TYPE status;
7993 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007994
Victor Stinner8c62be82010-05-06 00:08:46 +00007995 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
7996 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007997
Victor Stinner8c62be82010-05-06 00:08:46 +00007998 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007999}
8000#endif /* WTERMSIG */
8001
8002#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008003PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008004"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008005Return the signal that stopped the process that provided\n\
8006the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008007
8008static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008009posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008010{
Victor Stinner8c62be82010-05-06 00:08:46 +00008011 WAIT_TYPE status;
8012 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008013
Victor Stinner8c62be82010-05-06 00:08:46 +00008014 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8015 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008016
Victor Stinner8c62be82010-05-06 00:08:46 +00008017 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008018}
8019#endif /* WSTOPSIG */
8020
8021#endif /* HAVE_SYS_WAIT_H */
8022
8023
Thomas Wouters477c8d52006-05-27 19:21:47 +00008024#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00008025#ifdef _SCO_DS
8026/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
8027 needed definitions in sys/statvfs.h */
8028#define _SVID3
8029#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008030#include <sys/statvfs.h>
8031
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008032static PyObject*
8033_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008034 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8035 if (v == NULL)
8036 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008037
8038#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008039 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8040 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8041 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8042 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8043 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8044 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8045 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8046 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8047 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8048 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008049#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008050 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8051 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8052 PyStructSequence_SET_ITEM(v, 2,
8053 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8054 PyStructSequence_SET_ITEM(v, 3,
8055 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8056 PyStructSequence_SET_ITEM(v, 4,
8057 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8058 PyStructSequence_SET_ITEM(v, 5,
8059 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8060 PyStructSequence_SET_ITEM(v, 6,
8061 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8062 PyStructSequence_SET_ITEM(v, 7,
8063 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
8064 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8065 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008066#endif
8067
Victor Stinner8c62be82010-05-06 00:08:46 +00008068 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008069}
8070
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008071PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008072"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008073Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008074
8075static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008076posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008077{
Victor Stinner8c62be82010-05-06 00:08:46 +00008078 int fd, res;
8079 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008080
Victor Stinner8c62be82010-05-06 00:08:46 +00008081 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
8082 return NULL;
8083 Py_BEGIN_ALLOW_THREADS
8084 res = fstatvfs(fd, &st);
8085 Py_END_ALLOW_THREADS
8086 if (res != 0)
8087 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008088
Victor Stinner8c62be82010-05-06 00:08:46 +00008089 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008090}
Thomas Wouters477c8d52006-05-27 19:21:47 +00008091#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008092
8093
Thomas Wouters477c8d52006-05-27 19:21:47 +00008094#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008095#include <sys/statvfs.h>
8096
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008097PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008098"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008099Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008100
8101static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008102posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008103{
Victor Stinner6fa67772011-09-20 04:04:33 +02008104 PyObject *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008105 int res;
8106 struct statvfs st;
Victor Stinner6fa67772011-09-20 04:04:33 +02008107 if (!PyArg_ParseTuple(args, "O&:statvfs", PyUnicode_FSConverter, &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00008108 return NULL;
8109 Py_BEGIN_ALLOW_THREADS
Victor Stinner6fa67772011-09-20 04:04:33 +02008110 res = statvfs(PyBytes_AS_STRING(path), &st);
Victor Stinner8c62be82010-05-06 00:08:46 +00008111 Py_END_ALLOW_THREADS
Victor Stinner6fa67772011-09-20 04:04:33 +02008112 if (res != 0) {
8113 posix_error_with_filename(PyBytes_AS_STRING(path));
8114 Py_DECREF(path);
8115 return NULL;
8116 }
8117 Py_DECREF(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008118
Victor Stinner8c62be82010-05-06 00:08:46 +00008119 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008120}
8121#endif /* HAVE_STATVFS */
8122
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008123#ifdef MS_WINDOWS
8124PyDoc_STRVAR(win32__getdiskusage__doc__,
8125"_getdiskusage(path) -> (total, free)\n\n\
8126Return disk usage statistics about the given path as (total, free) tuple.");
8127
8128static PyObject *
8129win32__getdiskusage(PyObject *self, PyObject *args)
8130{
8131 BOOL retval;
8132 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01008133 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008134
Victor Stinner6139c1b2011-11-09 22:14:14 +01008135 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008136 return NULL;
8137
8138 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01008139 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008140 Py_END_ALLOW_THREADS
8141 if (retval == 0)
8142 return PyErr_SetFromWindowsErr(0);
8143
8144 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
8145}
8146#endif
8147
8148
Fred Drakec9680921999-12-13 16:37:25 +00008149/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
8150 * It maps strings representing configuration variable names to
8151 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00008152 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00008153 * rarely-used constants. There are three separate tables that use
8154 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00008155 *
8156 * This code is always included, even if none of the interfaces that
8157 * need it are included. The #if hackery needed to avoid it would be
8158 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00008159 */
8160struct constdef {
8161 char *name;
8162 long value;
8163};
8164
Fred Drake12c6e2d1999-12-14 21:25:03 +00008165static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008166conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00008167 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00008168{
Christian Heimes217cfd12007-12-02 14:31:20 +00008169 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008170 *valuep = PyLong_AS_LONG(arg);
8171 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00008172 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00008173 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00008174 /* look up the value in the table using a binary search */
8175 size_t lo = 0;
8176 size_t mid;
8177 size_t hi = tablesize;
8178 int cmp;
8179 const char *confname;
8180 if (!PyUnicode_Check(arg)) {
8181 PyErr_SetString(PyExc_TypeError,
8182 "configuration names must be strings or integers");
8183 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008184 }
Stefan Krah0e803b32010-11-26 16:16:47 +00008185 confname = _PyUnicode_AsString(arg);
8186 if (confname == NULL)
8187 return 0;
8188 while (lo < hi) {
8189 mid = (lo + hi) / 2;
8190 cmp = strcmp(confname, table[mid].name);
8191 if (cmp < 0)
8192 hi = mid;
8193 else if (cmp > 0)
8194 lo = mid + 1;
8195 else {
8196 *valuep = table[mid].value;
8197 return 1;
8198 }
8199 }
8200 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
8201 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008202 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00008203}
8204
8205
8206#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
8207static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008208#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008209 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008210#endif
8211#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008212 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008213#endif
Fred Drakec9680921999-12-13 16:37:25 +00008214#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008215 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008216#endif
8217#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00008218 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00008219#endif
8220#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00008221 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00008222#endif
8223#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00008224 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00008225#endif
8226#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008227 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008228#endif
8229#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00008230 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00008231#endif
8232#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008233 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00008234#endif
8235#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008236 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008237#endif
8238#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008239 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00008240#endif
8241#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008242 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008243#endif
8244#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008245 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00008246#endif
8247#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008248 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008249#endif
8250#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008251 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00008252#endif
8253#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008254 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008255#endif
8256#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008257 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00008258#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00008259#ifdef _PC_ACL_ENABLED
8260 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
8261#endif
8262#ifdef _PC_MIN_HOLE_SIZE
8263 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
8264#endif
8265#ifdef _PC_ALLOC_SIZE_MIN
8266 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
8267#endif
8268#ifdef _PC_REC_INCR_XFER_SIZE
8269 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
8270#endif
8271#ifdef _PC_REC_MAX_XFER_SIZE
8272 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
8273#endif
8274#ifdef _PC_REC_MIN_XFER_SIZE
8275 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
8276#endif
8277#ifdef _PC_REC_XFER_ALIGN
8278 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
8279#endif
8280#ifdef _PC_SYMLINK_MAX
8281 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
8282#endif
8283#ifdef _PC_XATTR_ENABLED
8284 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
8285#endif
8286#ifdef _PC_XATTR_EXISTS
8287 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
8288#endif
8289#ifdef _PC_TIMESTAMP_RESOLUTION
8290 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
8291#endif
Fred Drakec9680921999-12-13 16:37:25 +00008292};
8293
Fred Drakec9680921999-12-13 16:37:25 +00008294static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008295conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008296{
8297 return conv_confname(arg, valuep, posix_constants_pathconf,
8298 sizeof(posix_constants_pathconf)
8299 / sizeof(struct constdef));
8300}
8301#endif
8302
8303#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008304PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008305"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008306Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008307If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00008308
8309static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008310posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008311{
8312 PyObject *result = NULL;
8313 int name, fd;
8314
Fred Drake12c6e2d1999-12-14 21:25:03 +00008315 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
8316 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008317 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008318
Stefan Krah0e803b32010-11-26 16:16:47 +00008319 errno = 0;
8320 limit = fpathconf(fd, name);
8321 if (limit == -1 && errno != 0)
8322 posix_error();
8323 else
8324 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008325 }
8326 return result;
8327}
8328#endif
8329
8330
8331#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008332PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008333"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008334Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008335If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00008336
8337static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008338posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008339{
8340 PyObject *result = NULL;
8341 int name;
8342 char *path;
8343
8344 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
8345 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008346 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008347
Victor Stinner8c62be82010-05-06 00:08:46 +00008348 errno = 0;
8349 limit = pathconf(path, name);
8350 if (limit == -1 && errno != 0) {
8351 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00008352 /* could be a path or name problem */
8353 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00008354 else
Stefan Krah99439262010-11-26 12:58:05 +00008355 posix_error_with_filename(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00008356 }
8357 else
8358 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008359 }
8360 return result;
8361}
8362#endif
8363
8364#ifdef HAVE_CONFSTR
8365static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008366#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00008367 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00008368#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00008369#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008370 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008371#endif
8372#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008373 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008374#endif
Fred Draked86ed291999-12-15 15:34:33 +00008375#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008376 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008377#endif
8378#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008379 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008380#endif
8381#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008382 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008383#endif
8384#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008385 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008386#endif
Fred Drakec9680921999-12-13 16:37:25 +00008387#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008388 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008389#endif
8390#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008391 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008392#endif
8393#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008394 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008395#endif
8396#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008397 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008398#endif
8399#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008400 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008401#endif
8402#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008403 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008404#endif
8405#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008406 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008407#endif
8408#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008409 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008410#endif
Fred Draked86ed291999-12-15 15:34:33 +00008411#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00008412 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00008413#endif
Fred Drakec9680921999-12-13 16:37:25 +00008414#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00008415 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00008416#endif
Fred Draked86ed291999-12-15 15:34:33 +00008417#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008418 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00008419#endif
8420#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008421 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00008422#endif
8423#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008424 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008425#endif
8426#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008427 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00008428#endif
Fred Drakec9680921999-12-13 16:37:25 +00008429#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008430 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008431#endif
8432#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008433 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008434#endif
8435#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008436 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008437#endif
8438#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008439 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008440#endif
8441#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008442 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008443#endif
8444#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008445 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008446#endif
8447#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008448 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008449#endif
8450#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008451 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008452#endif
8453#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008454 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008455#endif
8456#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008457 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008458#endif
8459#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008460 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008461#endif
8462#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008463 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008464#endif
8465#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008466 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008467#endif
8468#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008469 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008470#endif
8471#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008472 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008473#endif
8474#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008475 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008476#endif
Fred Draked86ed291999-12-15 15:34:33 +00008477#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008478 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008479#endif
8480#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008481 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00008482#endif
8483#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00008484 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00008485#endif
8486#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008487 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008488#endif
8489#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008490 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008491#endif
8492#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00008493 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00008494#endif
8495#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008496 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00008497#endif
8498#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00008499 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00008500#endif
8501#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008502 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008503#endif
8504#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008505 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008506#endif
8507#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008508 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008509#endif
8510#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008511 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008512#endif
8513#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00008514 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00008515#endif
Fred Drakec9680921999-12-13 16:37:25 +00008516};
8517
8518static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008519conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008520{
8521 return conv_confname(arg, valuep, posix_constants_confstr,
8522 sizeof(posix_constants_confstr)
8523 / sizeof(struct constdef));
8524}
8525
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008526PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008527"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008528Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008529
8530static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008531posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008532{
8533 PyObject *result = NULL;
8534 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00008535 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00008536 int len;
Fred Drakec9680921999-12-13 16:37:25 +00008537
Victor Stinnercb043522010-09-10 23:49:04 +00008538 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
8539 return NULL;
8540
8541 errno = 0;
8542 len = confstr(name, buffer, sizeof(buffer));
8543 if (len == 0) {
8544 if (errno) {
8545 posix_error();
8546 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00008547 }
8548 else {
Victor Stinnercb043522010-09-10 23:49:04 +00008549 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00008550 }
8551 }
Victor Stinnercb043522010-09-10 23:49:04 +00008552
8553 if ((unsigned int)len >= sizeof(buffer)) {
8554 char *buf = PyMem_Malloc(len);
8555 if (buf == NULL)
8556 return PyErr_NoMemory();
8557 confstr(name, buf, len);
8558 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
8559 PyMem_Free(buf);
8560 }
8561 else
8562 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00008563 return result;
8564}
8565#endif
8566
8567
8568#ifdef HAVE_SYSCONF
8569static struct constdef posix_constants_sysconf[] = {
8570#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008571 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00008572#endif
8573#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00008574 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00008575#endif
8576#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008577 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008578#endif
8579#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008580 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008581#endif
8582#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008583 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008584#endif
8585#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00008586 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00008587#endif
8588#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00008589 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00008590#endif
8591#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008592 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008593#endif
8594#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00008595 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00008596#endif
8597#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008598 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008599#endif
Fred Draked86ed291999-12-15 15:34:33 +00008600#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008601 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008602#endif
8603#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00008604 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00008605#endif
Fred Drakec9680921999-12-13 16:37:25 +00008606#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008607 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008608#endif
Fred Drakec9680921999-12-13 16:37:25 +00008609#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008610 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008611#endif
8612#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008613 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008614#endif
8615#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008616 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008617#endif
8618#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008619 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008620#endif
8621#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008622 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008623#endif
Fred Draked86ed291999-12-15 15:34:33 +00008624#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008625 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00008626#endif
Fred Drakec9680921999-12-13 16:37:25 +00008627#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00008628 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008629#endif
8630#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008631 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008632#endif
8633#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008634 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008635#endif
8636#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008637 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008638#endif
8639#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008640 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008641#endif
Fred Draked86ed291999-12-15 15:34:33 +00008642#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00008643 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00008644#endif
Fred Drakec9680921999-12-13 16:37:25 +00008645#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008646 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008647#endif
8648#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008649 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008650#endif
8651#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008652 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008653#endif
8654#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008655 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008656#endif
8657#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008658 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008659#endif
8660#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008661 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00008662#endif
8663#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008664 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008665#endif
8666#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008667 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008668#endif
8669#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00008670 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008671#endif
8672#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008673 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008674#endif
8675#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008676 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008677#endif
8678#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008679 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008680#endif
8681#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008682 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008683#endif
8684#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008685 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008686#endif
8687#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008688 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008689#endif
8690#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008691 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008692#endif
8693#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008694 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00008695#endif
8696#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008697 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008698#endif
8699#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008700 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008701#endif
8702#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00008703 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008704#endif
8705#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008706 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008707#endif
8708#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008709 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008710#endif
8711#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008712 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008713#endif
Fred Draked86ed291999-12-15 15:34:33 +00008714#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00008715 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00008716#endif
Fred Drakec9680921999-12-13 16:37:25 +00008717#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008718 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008719#endif
8720#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008721 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008722#endif
8723#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008724 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008725#endif
Fred Draked86ed291999-12-15 15:34:33 +00008726#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008727 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00008728#endif
Fred Drakec9680921999-12-13 16:37:25 +00008729#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00008730 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00008731#endif
Fred Draked86ed291999-12-15 15:34:33 +00008732#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00008733 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00008734#endif
8735#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00008736 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00008737#endif
Fred Drakec9680921999-12-13 16:37:25 +00008738#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008739 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008740#endif
8741#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008742 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008743#endif
8744#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008745 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008746#endif
8747#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008748 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008749#endif
Fred Draked86ed291999-12-15 15:34:33 +00008750#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00008751 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00008752#endif
Fred Drakec9680921999-12-13 16:37:25 +00008753#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00008754 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00008755#endif
8756#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00008757 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00008758#endif
8759#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008760 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008761#endif
8762#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008763 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00008764#endif
8765#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00008766 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00008767#endif
8768#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00008769 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00008770#endif
8771#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00008772 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00008773#endif
Fred Draked86ed291999-12-15 15:34:33 +00008774#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00008775 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00008776#endif
Fred Drakec9680921999-12-13 16:37:25 +00008777#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008778 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008779#endif
8780#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008781 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008782#endif
Fred Draked86ed291999-12-15 15:34:33 +00008783#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008784 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008785#endif
Fred Drakec9680921999-12-13 16:37:25 +00008786#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008787 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008788#endif
8789#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008790 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008791#endif
8792#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008793 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008794#endif
8795#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008796 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008797#endif
8798#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008799 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008800#endif
8801#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008802 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008803#endif
8804#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008805 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008806#endif
8807#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008808 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00008809#endif
8810#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00008811 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00008812#endif
Fred Draked86ed291999-12-15 15:34:33 +00008813#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008814 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00008815#endif
8816#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00008817 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00008818#endif
Fred Drakec9680921999-12-13 16:37:25 +00008819#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00008820 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00008821#endif
8822#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008823 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008824#endif
8825#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00008826 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008827#endif
8828#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00008829 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008830#endif
8831#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008832 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008833#endif
8834#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00008835 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008836#endif
8837#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00008838 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00008839#endif
8840#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00008841 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00008842#endif
8843#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00008844 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00008845#endif
8846#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00008847 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00008848#endif
8849#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00008850 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00008851#endif
8852#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008853 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00008854#endif
8855#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008856 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00008857#endif
8858#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00008859 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00008860#endif
8861#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00008862 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00008863#endif
8864#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00008865 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00008866#endif
8867#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00008868 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00008869#endif
8870#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008871 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008872#endif
8873#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00008874 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008875#endif
8876#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00008877 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00008878#endif
8879#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008880 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008881#endif
8882#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008883 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008884#endif
8885#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00008886 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00008887#endif
8888#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008889 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008890#endif
8891#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008892 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008893#endif
8894#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008895 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00008896#endif
8897#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00008898 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00008899#endif
8900#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008901 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008902#endif
8903#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008904 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008905#endif
8906#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008907 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00008908#endif
8909#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008910 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008911#endif
8912#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008913 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008914#endif
8915#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008916 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008917#endif
8918#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008919 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008920#endif
8921#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008922 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008923#endif
Fred Draked86ed291999-12-15 15:34:33 +00008924#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00008925 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00008926#endif
Fred Drakec9680921999-12-13 16:37:25 +00008927#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00008928 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00008929#endif
8930#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008931 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008932#endif
8933#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00008934 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00008935#endif
8936#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008937 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008938#endif
8939#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008940 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008941#endif
8942#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00008943 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008944#endif
8945#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00008946 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00008947#endif
8948#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00008949 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008950#endif
8951#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00008952 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008953#endif
8954#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008955 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008956#endif
8957#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00008958 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008959#endif
8960#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008961 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00008962#endif
8963#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008964 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00008965#endif
8966#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00008967 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00008968#endif
8969#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00008970 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008971#endif
8972#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008973 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008974#endif
8975#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008976 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008977#endif
8978#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00008979 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00008980#endif
8981#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008982 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008983#endif
8984#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008985 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008986#endif
8987#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008988 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008989#endif
8990#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008991 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008992#endif
8993#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008994 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008995#endif
8996#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008997 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008998#endif
8999#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00009000 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00009001#endif
9002#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009003 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009004#endif
9005#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009006 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009007#endif
9008#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009009 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009010#endif
9011#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009012 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009013#endif
9014#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00009015 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00009016#endif
9017#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009018 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009019#endif
9020#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00009021 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00009022#endif
9023#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009024 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009025#endif
9026#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00009027 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00009028#endif
9029#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00009030 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00009031#endif
9032#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00009033 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00009034#endif
9035#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00009036 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00009037#endif
9038#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009039 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009040#endif
9041#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00009042 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00009043#endif
9044#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00009045 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00009046#endif
9047#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009048 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009049#endif
9050#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009051 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009052#endif
9053#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00009054 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00009055#endif
9056#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00009057 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00009058#endif
9059#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00009060 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00009061#endif
9062};
9063
9064static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009065conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009066{
9067 return conv_confname(arg, valuep, posix_constants_sysconf,
9068 sizeof(posix_constants_sysconf)
9069 / sizeof(struct constdef));
9070}
9071
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009072PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009073"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009074Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009075
9076static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009077posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009078{
9079 PyObject *result = NULL;
9080 int name;
9081
9082 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
9083 int value;
9084
9085 errno = 0;
9086 value = sysconf(name);
9087 if (value == -1 && errno != 0)
9088 posix_error();
9089 else
Christian Heimes217cfd12007-12-02 14:31:20 +00009090 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00009091 }
9092 return result;
9093}
9094#endif
9095
9096
Fred Drakebec628d1999-12-15 18:31:10 +00009097/* This code is used to ensure that the tables of configuration value names
9098 * are in sorted order as required by conv_confname(), and also to build the
9099 * the exported dictionaries that are used to publish information about the
9100 * names available on the host platform.
9101 *
9102 * Sorting the table at runtime ensures that the table is properly ordered
9103 * when used, even for platforms we're not able to test on. It also makes
9104 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00009105 */
Fred Drakebec628d1999-12-15 18:31:10 +00009106
9107static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009108cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00009109{
9110 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009111 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00009112 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009113 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00009114
9115 return strcmp(c1->name, c2->name);
9116}
9117
9118static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009119setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00009120 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009121{
Fred Drakebec628d1999-12-15 18:31:10 +00009122 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00009123 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00009124
9125 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
9126 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00009127 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00009128 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009129
Barry Warsaw3155db32000-04-13 15:20:40 +00009130 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009131 PyObject *o = PyLong_FromLong(table[i].value);
9132 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
9133 Py_XDECREF(o);
9134 Py_DECREF(d);
9135 return -1;
9136 }
9137 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00009138 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00009139 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00009140}
9141
Fred Drakebec628d1999-12-15 18:31:10 +00009142/* Return -1 on failure, 0 on success. */
9143static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00009144setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009145{
9146#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00009147 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00009148 sizeof(posix_constants_pathconf)
9149 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009150 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009151 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009152#endif
9153#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00009154 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00009155 sizeof(posix_constants_confstr)
9156 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009157 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009158 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009159#endif
9160#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00009161 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00009162 sizeof(posix_constants_sysconf)
9163 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009164 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009165 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009166#endif
Fred Drakebec628d1999-12-15 18:31:10 +00009167 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00009168}
Fred Draked86ed291999-12-15 15:34:33 +00009169
9170
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009171PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009172"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009173Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009174in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009175
9176static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009177posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009178{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009179 abort();
9180 /*NOTREACHED*/
9181 Py_FatalError("abort() called from Python code didn't abort!");
9182 return NULL;
9183}
Fred Drakebec628d1999-12-15 18:31:10 +00009184
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00009185#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009186PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00009187"startfile(filepath [, operation]) - Start a file with its associated\n\
9188application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009189\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00009190When \"operation\" is not specified or \"open\", this acts like\n\
9191double-clicking the file in Explorer, or giving the file name as an\n\
9192argument to the DOS \"start\" command: the file is opened with whatever\n\
9193application (if any) its extension is associated.\n\
9194When another \"operation\" is given, it specifies what should be done with\n\
9195the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009196\n\
9197startfile returns as soon as the associated application is launched.\n\
9198There is no option to wait for the application to close, and no way\n\
9199to retrieve the application's exit status.\n\
9200\n\
9201The filepath is relative to the current directory. If you want to use\n\
9202an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009203the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00009204
9205static PyObject *
9206win32_startfile(PyObject *self, PyObject *args)
9207{
Victor Stinner8c62be82010-05-06 00:08:46 +00009208 PyObject *ofilepath;
9209 char *filepath;
9210 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02009211 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +00009212 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00009213
Victor Stinnereb5657a2011-09-30 01:44:27 +02009214 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009215 if (!PyArg_ParseTuple(args, "U|s:startfile",
9216 &unipath, &operation)) {
9217 PyErr_Clear();
9218 goto normal;
9219 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009220
Victor Stinner8c62be82010-05-06 00:08:46 +00009221 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009222 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +00009223 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +02009224 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009225 PyErr_Clear();
9226 operation = NULL;
9227 goto normal;
9228 }
9229 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009230
Victor Stinnereb5657a2011-09-30 01:44:27 +02009231 wpath = PyUnicode_AsUnicode(unipath);
9232 if (wpath == NULL)
9233 goto normal;
9234 if (uoperation) {
9235 woperation = PyUnicode_AsUnicode(uoperation);
9236 if (woperation == NULL)
9237 goto normal;
9238 }
9239 else
9240 woperation = NULL;
9241
Victor Stinner8c62be82010-05-06 00:08:46 +00009242 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02009243 rc = ShellExecuteW((HWND)0, woperation, wpath,
9244 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +00009245 Py_END_ALLOW_THREADS
9246
Victor Stinnereb5657a2011-09-30 01:44:27 +02009247 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +00009248 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009249 win32_error_object("startfile", unipath);
9250 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009251 }
9252 Py_INCREF(Py_None);
9253 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009254
9255normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00009256 if (!PyArg_ParseTuple(args, "O&|s:startfile",
9257 PyUnicode_FSConverter, &ofilepath,
9258 &operation))
9259 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01009260 if (win32_warn_bytes_api()) {
9261 Py_DECREF(ofilepath);
9262 return NULL;
9263 }
Victor Stinner8c62be82010-05-06 00:08:46 +00009264 filepath = PyBytes_AsString(ofilepath);
9265 Py_BEGIN_ALLOW_THREADS
9266 rc = ShellExecute((HWND)0, operation, filepath,
9267 NULL, NULL, SW_SHOWNORMAL);
9268 Py_END_ALLOW_THREADS
9269 if (rc <= (HINSTANCE)32) {
9270 PyObject *errval = win32_error("startfile", filepath);
9271 Py_DECREF(ofilepath);
9272 return errval;
9273 }
9274 Py_DECREF(ofilepath);
9275 Py_INCREF(Py_None);
9276 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00009277}
9278#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009279
Martin v. Löwis438b5342002-12-27 10:16:42 +00009280#ifdef HAVE_GETLOADAVG
9281PyDoc_STRVAR(posix_getloadavg__doc__,
9282"getloadavg() -> (float, float, float)\n\n\
9283Return the number of processes in the system run queue averaged over\n\
9284the last 1, 5, and 15 minutes or raises OSError if the load average\n\
9285was unobtainable");
9286
9287static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009288posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00009289{
9290 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00009291 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009292 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
9293 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00009294 } else
Stefan Krah0e803b32010-11-26 16:16:47 +00009295 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00009296}
9297#endif
9298
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009299PyDoc_STRVAR(device_encoding__doc__,
9300"device_encoding(fd) -> str\n\n\
9301Return a string describing the encoding of the device\n\
9302if the output is a terminal; else return None.");
9303
9304static PyObject *
9305device_encoding(PyObject *self, PyObject *args)
9306{
Victor Stinner8c62be82010-05-06 00:08:46 +00009307 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -05009308
Victor Stinner8c62be82010-05-06 00:08:46 +00009309 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
9310 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -05009311
9312 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009313}
9314
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009315#ifdef __VMS
9316/* Use openssl random routine */
9317#include <openssl/rand.h>
9318PyDoc_STRVAR(vms_urandom__doc__,
9319"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00009320Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009321
9322static PyObject*
9323vms_urandom(PyObject *self, PyObject *args)
9324{
Victor Stinner8c62be82010-05-06 00:08:46 +00009325 int howMany;
9326 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009327
Victor Stinner8c62be82010-05-06 00:08:46 +00009328 /* Read arguments */
9329 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
9330 return NULL;
9331 if (howMany < 0)
9332 return PyErr_Format(PyExc_ValueError,
9333 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009334
Victor Stinner8c62be82010-05-06 00:08:46 +00009335 /* Allocate bytes */
9336 result = PyBytes_FromStringAndSize(NULL, howMany);
9337 if (result != NULL) {
9338 /* Get random data */
9339 if (RAND_pseudo_bytes((unsigned char*)
9340 PyBytes_AS_STRING(result),
9341 howMany) < 0) {
9342 Py_DECREF(result);
9343 return PyErr_Format(PyExc_ValueError,
9344 "RAND_pseudo_bytes");
9345 }
9346 }
9347 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009348}
9349#endif
9350
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009351#ifdef HAVE_SETRESUID
9352PyDoc_STRVAR(posix_setresuid__doc__,
9353"setresuid(ruid, euid, suid)\n\n\
9354Set the current process's real, effective, and saved user ids.");
9355
9356static PyObject*
9357posix_setresuid (PyObject *self, PyObject *args)
9358{
Victor Stinner8c62be82010-05-06 00:08:46 +00009359 /* We assume uid_t is no larger than a long. */
9360 long ruid, euid, suid;
9361 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
9362 return NULL;
9363 if (setresuid(ruid, euid, suid) < 0)
9364 return posix_error();
9365 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009366}
9367#endif
9368
9369#ifdef HAVE_SETRESGID
9370PyDoc_STRVAR(posix_setresgid__doc__,
9371"setresgid(rgid, egid, sgid)\n\n\
9372Set the current process's real, effective, and saved group ids.");
9373
9374static PyObject*
9375posix_setresgid (PyObject *self, PyObject *args)
9376{
Victor Stinner8c62be82010-05-06 00:08:46 +00009377 /* We assume uid_t is no larger than a long. */
9378 long rgid, egid, sgid;
9379 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
9380 return NULL;
9381 if (setresgid(rgid, egid, sgid) < 0)
9382 return posix_error();
9383 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009384}
9385#endif
9386
9387#ifdef HAVE_GETRESUID
9388PyDoc_STRVAR(posix_getresuid__doc__,
9389"getresuid() -> (ruid, euid, suid)\n\n\
9390Get tuple of the current process's real, effective, and saved user ids.");
9391
9392static PyObject*
9393posix_getresuid (PyObject *self, PyObject *noargs)
9394{
Victor Stinner8c62be82010-05-06 00:08:46 +00009395 uid_t ruid, euid, suid;
9396 long l_ruid, l_euid, l_suid;
9397 if (getresuid(&ruid, &euid, &suid) < 0)
9398 return posix_error();
9399 /* Force the values into long's as we don't know the size of uid_t. */
9400 l_ruid = ruid;
9401 l_euid = euid;
9402 l_suid = suid;
9403 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009404}
9405#endif
9406
9407#ifdef HAVE_GETRESGID
9408PyDoc_STRVAR(posix_getresgid__doc__,
9409"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00009410Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009411
9412static PyObject*
9413posix_getresgid (PyObject *self, PyObject *noargs)
9414{
Victor Stinner8c62be82010-05-06 00:08:46 +00009415 uid_t rgid, egid, sgid;
9416 long l_rgid, l_egid, l_sgid;
9417 if (getresgid(&rgid, &egid, &sgid) < 0)
9418 return posix_error();
9419 /* Force the values into long's as we don't know the size of uid_t. */
9420 l_rgid = rgid;
9421 l_egid = egid;
9422 l_sgid = sgid;
9423 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009424}
9425#endif
9426
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009427/* Posix *at family of functions:
9428 faccessat, fchmodat, fchownat, fstatat, futimesat,
9429 linkat, mkdirat, mknodat, openat, readlinkat, renameat, symlinkat,
9430 unlinkat, utimensat, mkfifoat */
9431
9432#ifdef HAVE_FACCESSAT
9433PyDoc_STRVAR(posix_faccessat__doc__,
9434"faccessat(dirfd, path, mode, flags=0) -> True if granted, False otherwise\n\n\
9435Like access() but if path is relative, it is taken as relative to dirfd.\n\
9436flags is optional and can be constructed by ORing together zero or more\n\
9437of these values: AT_SYMLINK_NOFOLLOW, AT_EACCESS.\n\
9438If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9439is interpreted relative to the current working directory.");
9440
9441static PyObject *
9442posix_faccessat(PyObject *self, PyObject *args)
9443{
9444 PyObject *opath;
9445 char *path;
9446 int mode;
9447 int res;
9448 int dirfd, flags = 0;
9449 if (!PyArg_ParseTuple(args, "iO&i|i:faccessat",
9450 &dirfd, PyUnicode_FSConverter, &opath, &mode, &flags))
9451 return NULL;
9452 path = PyBytes_AsString(opath);
9453 Py_BEGIN_ALLOW_THREADS
9454 res = faccessat(dirfd, path, mode, flags);
9455 Py_END_ALLOW_THREADS
9456 Py_DECREF(opath);
9457 return PyBool_FromLong(res == 0);
9458}
9459#endif
9460
9461#ifdef HAVE_FCHMODAT
9462PyDoc_STRVAR(posix_fchmodat__doc__,
9463"fchmodat(dirfd, path, mode, flags=0)\n\n\
9464Like chmod() but if path is relative, it is taken as relative to dirfd.\n\
9465flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9466If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9467is interpreted relative to the current working directory.");
9468
9469static PyObject *
9470posix_fchmodat(PyObject *self, PyObject *args)
9471{
9472 int dirfd, mode, res;
9473 int flags = 0;
9474 PyObject *opath;
9475 char *path;
9476
9477 if (!PyArg_ParseTuple(args, "iO&i|i:fchmodat",
9478 &dirfd, PyUnicode_FSConverter, &opath, &mode, &flags))
9479 return NULL;
9480
9481 path = PyBytes_AsString(opath);
9482
9483 Py_BEGIN_ALLOW_THREADS
9484 res = fchmodat(dirfd, path, mode, flags);
9485 Py_END_ALLOW_THREADS
9486 Py_DECREF(opath);
9487 if (res < 0)
9488 return posix_error();
9489 Py_RETURN_NONE;
9490}
9491#endif /* HAVE_FCHMODAT */
9492
9493#ifdef HAVE_FCHOWNAT
9494PyDoc_STRVAR(posix_fchownat__doc__,
9495"fchownat(dirfd, path, uid, gid, flags=0)\n\n\
9496Like chown() but if path is relative, it is taken as relative to dirfd.\n\
9497flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9498If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9499is interpreted relative to the current working directory.");
9500
9501static PyObject *
9502posix_fchownat(PyObject *self, PyObject *args)
9503{
9504 PyObject *opath;
9505 int dirfd, res;
9506 long uid, gid;
9507 int flags = 0;
9508 char *path;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009509
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009510 if (!PyArg_ParseTuple(args, "iO&ll|i:fchownat",
9511 &dirfd, PyUnicode_FSConverter, &opath, &uid, &gid, &flags))
9512 return NULL;
9513
9514 path = PyBytes_AsString(opath);
9515
9516 Py_BEGIN_ALLOW_THREADS
9517 res = fchownat(dirfd, path, (uid_t) uid, (gid_t) gid, flags);
9518 Py_END_ALLOW_THREADS
9519 Py_DECREF(opath);
9520 if (res < 0)
9521 return posix_error();
9522 Py_RETURN_NONE;
9523}
9524#endif /* HAVE_FCHOWNAT */
9525
9526#ifdef HAVE_FSTATAT
9527PyDoc_STRVAR(posix_fstatat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01009528"fstatat(dirfd, path, flags=0) -> stat result\n\n\
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009529Like stat() but if path is relative, it is taken as relative to dirfd.\n\
9530flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9531If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9532is interpreted relative to the current working directory.");
9533
9534static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01009535posix_fstatat(PyObject *self, PyObject *args)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009536{
9537 PyObject *opath;
9538 char *path;
9539 STRUCT_STAT st;
9540 int dirfd, res, flags = 0;
9541
Victor Stinner4195b5c2012-02-08 23:03:19 +01009542 if (!PyArg_ParseTuple(args, "iO&|i:fstatat",
9543 &dirfd, PyUnicode_FSConverter, &opath, &flags))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009544 return NULL;
9545 path = PyBytes_AsString(opath);
9546
9547 Py_BEGIN_ALLOW_THREADS
9548 res = fstatat(dirfd, path, &st, flags);
9549 Py_END_ALLOW_THREADS
9550 Py_DECREF(opath);
9551 if (res != 0)
9552 return posix_error();
9553
Victor Stinner4195b5c2012-02-08 23:03:19 +01009554 return _pystat_fromstructstat(&st);
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009555}
9556#endif
9557
9558#ifdef HAVE_FUTIMESAT
9559PyDoc_STRVAR(posix_futimesat__doc__,
Brian Curtin7ef53ef2011-11-07 14:38:24 -06009560"futimesat(dirfd, path[, (atime, mtime)])\n\
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009561Like utime() but if path is relative, it is taken as relative to dirfd.\n\
9562If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9563is interpreted relative to the current working directory.");
9564
9565static PyObject *
9566posix_futimesat(PyObject *self, PyObject *args)
9567{
9568 PyObject *opath;
9569 char *path;
9570 int res, dirfd;
Brian Curtin7ef53ef2011-11-07 14:38:24 -06009571 PyObject* arg = Py_None;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009572 time_t atime, mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01009573 long ansec, mnsec;
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009574
Brian Curtin7ef53ef2011-11-07 14:38:24 -06009575 if (!PyArg_ParseTuple(args, "iO&|O:futimesat",
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009576 &dirfd, PyUnicode_FSConverter, &opath, &arg))
9577 return NULL;
9578 path = PyBytes_AsString(opath);
9579 if (arg == Py_None) {
9580 /* optional time values not given */
9581 Py_BEGIN_ALLOW_THREADS
9582 res = futimesat(dirfd, path, NULL);
9583 Py_END_ALLOW_THREADS
9584 }
9585 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
9586 PyErr_SetString(PyExc_TypeError,
9587 "futimesat() arg 3 must be a tuple (atime, mtime)");
9588 Py_DECREF(opath);
9589 return NULL;
9590 }
9591 else {
Victor Stinner5d272cc2012-03-13 13:35:55 +01009592 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(arg, 0),
9593 &atime, &ansec) == -1) {
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009594 Py_DECREF(opath);
9595 return NULL;
9596 }
Victor Stinner5d272cc2012-03-13 13:35:55 +01009597 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(arg, 1),
9598 &mtime, &mnsec) == -1) {
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009599 Py_DECREF(opath);
9600 return NULL;
9601 }
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009602
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009603 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009604 {
9605#ifdef HAVE_UTIMENSAT
9606 struct timespec buf[2];
9607 buf[0].tv_sec = atime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01009608 buf[0].tv_nsec = ansec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009609 buf[1].tv_sec = mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01009610 buf[1].tv_nsec = mnsec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009611 res = utimensat(dirfd, path, buf, 0);
9612#else
9613 struct timeval buf[2];
9614 buf[0].tv_sec = atime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01009615 buf[0].tv_usec = ansec / 1000;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009616 buf[1].tv_sec = mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01009617 buf[1].tv_usec = mnsec / 1000;
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009618 res = futimesat(dirfd, path, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009619#endif
9620 }
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009621 Py_END_ALLOW_THREADS
9622 }
9623 Py_DECREF(opath);
9624 if (res < 0) {
9625 return posix_error();
9626 }
9627 Py_RETURN_NONE;
9628}
9629#endif
9630
9631#ifdef HAVE_LINKAT
9632PyDoc_STRVAR(posix_linkat__doc__,
9633"linkat(srcfd, srcpath, dstfd, dstpath, flags=0)\n\n\
9634Like link() but if srcpath is relative, it is taken as relative to srcfd\n\
9635and if dstpath is relative, it is taken as relative to dstfd.\n\
9636flags is optional and may be 0 or AT_SYMLINK_FOLLOW.\n\
9637If srcpath is relative and srcfd is the special value AT_FDCWD, then\n\
9638srcpath is interpreted relative to the current working directory. This\n\
9639also applies for dstpath.");
9640
9641static PyObject *
9642posix_linkat(PyObject *self, PyObject *args)
9643{
9644 PyObject *osrc, *odst;
9645 char *src, *dst;
9646 int res, srcfd, dstfd;
9647 int flags = 0;
9648
9649 if (!PyArg_ParseTuple(args, "iO&iO&|i:linkat",
9650 &srcfd, PyUnicode_FSConverter, &osrc, &dstfd, PyUnicode_FSConverter, &odst, &flags))
9651 return NULL;
9652 src = PyBytes_AsString(osrc);
9653 dst = PyBytes_AsString(odst);
9654 Py_BEGIN_ALLOW_THREADS
9655 res = linkat(srcfd, src, dstfd, dst, flags);
9656 Py_END_ALLOW_THREADS
9657 Py_DECREF(osrc);
9658 Py_DECREF(odst);
9659 if (res < 0)
9660 return posix_error();
9661 Py_RETURN_NONE;
9662}
9663#endif /* HAVE_LINKAT */
9664
9665#ifdef HAVE_MKDIRAT
9666PyDoc_STRVAR(posix_mkdirat__doc__,
9667"mkdirat(dirfd, path, mode=0o777)\n\n\
9668Like mkdir() but if path is relative, it is taken as relative to dirfd.\n\
9669If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9670is interpreted relative to the current working directory.");
9671
9672static PyObject *
9673posix_mkdirat(PyObject *self, PyObject *args)
9674{
9675 int res, dirfd;
9676 PyObject *opath;
9677 char *path;
9678 int mode = 0777;
9679
9680 if (!PyArg_ParseTuple(args, "iO&|i:mkdirat",
9681 &dirfd, PyUnicode_FSConverter, &opath, &mode))
9682 return NULL;
9683 path = PyBytes_AsString(opath);
9684 Py_BEGIN_ALLOW_THREADS
9685 res = mkdirat(dirfd, path, mode);
9686 Py_END_ALLOW_THREADS
9687 Py_DECREF(opath);
9688 if (res < 0)
9689 return posix_error();
9690 Py_RETURN_NONE;
9691}
9692#endif
9693
9694#if defined(HAVE_MKNODAT) && defined(HAVE_MAKEDEV)
9695PyDoc_STRVAR(posix_mknodat__doc__,
9696"mknodat(dirfd, path, mode=0o600, device=0)\n\n\
9697Like mknod() but if path is relative, it is taken as relative to dirfd.\n\
9698If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9699is interpreted relative to the current working directory.");
9700
9701static PyObject *
9702posix_mknodat(PyObject *self, PyObject *args)
9703{
9704 PyObject *opath;
9705 char *filename;
9706 int mode = 0600;
9707 int device = 0;
9708 int res, dirfd;
9709 if (!PyArg_ParseTuple(args, "iO&|ii:mknodat", &dirfd,
9710 PyUnicode_FSConverter, &opath, &mode, &device))
9711 return NULL;
9712 filename = PyBytes_AS_STRING(opath);
9713 Py_BEGIN_ALLOW_THREADS
9714 res = mknodat(dirfd, filename, mode, device);
9715 Py_END_ALLOW_THREADS
9716 Py_DECREF(opath);
9717 if (res < 0)
9718 return posix_error();
9719 Py_RETURN_NONE;
9720}
9721#endif
9722
9723#ifdef HAVE_OPENAT
9724PyDoc_STRVAR(posix_openat__doc__,
9725"openat(dirfd, path, flag, mode=0o777) -> fd\n\n\
9726Like open() but if path is relative, it is taken as relative to dirfd.\n\
9727If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9728is interpreted relative to the current working directory.");
9729
9730static PyObject *
9731posix_openat(PyObject *self, PyObject *args)
9732{
9733 PyObject *ofile;
9734 char *file;
9735 int flag, dirfd, fd;
9736 int mode = 0777;
9737
9738 if (!PyArg_ParseTuple(args, "iO&i|i:openat",
9739 &dirfd, PyUnicode_FSConverter, &ofile,
9740 &flag, &mode))
9741 return NULL;
9742 file = PyBytes_AsString(ofile);
9743 Py_BEGIN_ALLOW_THREADS
9744 fd = openat(dirfd, file, flag, mode);
9745 Py_END_ALLOW_THREADS
9746 Py_DECREF(ofile);
9747 if (fd < 0)
9748 return posix_error();
9749 return PyLong_FromLong((long)fd);
9750}
9751#endif
9752
9753#ifdef HAVE_READLINKAT
9754PyDoc_STRVAR(posix_readlinkat__doc__,
9755"readlinkat(dirfd, path) -> path\n\n\
9756Like readlink() but if path is relative, it is taken as relative to dirfd.\n\
9757If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9758is interpreted relative to the current working directory.");
9759
9760static PyObject *
9761posix_readlinkat(PyObject *self, PyObject *args)
9762{
9763 PyObject *v, *opath;
9764 char buf[MAXPATHLEN];
9765 char *path;
9766 int n, dirfd;
9767 int arg_is_unicode = 0;
9768
9769 if (!PyArg_ParseTuple(args, "iO&:readlinkat",
9770 &dirfd, PyUnicode_FSConverter, &opath))
9771 return NULL;
9772 path = PyBytes_AsString(opath);
9773 v = PySequence_GetItem(args, 1);
9774 if (v == NULL) {
9775 Py_DECREF(opath);
9776 return NULL;
9777 }
9778
9779 if (PyUnicode_Check(v)) {
9780 arg_is_unicode = 1;
9781 }
9782 Py_DECREF(v);
9783
9784 Py_BEGIN_ALLOW_THREADS
9785 n = readlinkat(dirfd, path, buf, (int) sizeof buf);
9786 Py_END_ALLOW_THREADS
9787 Py_DECREF(opath);
9788 if (n < 0)
9789 return posix_error();
9790
9791 if (arg_is_unicode)
9792 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
9793 else
9794 return PyBytes_FromStringAndSize(buf, n);
9795}
9796#endif /* HAVE_READLINKAT */
9797
9798#ifdef HAVE_RENAMEAT
9799PyDoc_STRVAR(posix_renameat__doc__,
9800"renameat(olddirfd, oldpath, newdirfd, newpath)\n\n\
9801Like rename() but if oldpath is relative, it is taken as relative to\n\
9802olddirfd and if newpath is relative, it is taken as relative to newdirfd.\n\
9803If oldpath is relative and olddirfd is the special value AT_FDCWD, then\n\
9804oldpath is interpreted relative to the current working directory. This\n\
9805also applies for newpath.");
9806
9807static PyObject *
9808posix_renameat(PyObject *self, PyObject *args)
9809{
9810 int res;
9811 PyObject *opathold, *opathnew;
9812 char *opath, *npath;
9813 int oldfd, newfd;
9814
9815 if (!PyArg_ParseTuple(args, "iO&iO&:renameat",
9816 &oldfd, PyUnicode_FSConverter, &opathold, &newfd, PyUnicode_FSConverter, &opathnew))
9817 return NULL;
9818 opath = PyBytes_AsString(opathold);
9819 npath = PyBytes_AsString(opathnew);
9820 Py_BEGIN_ALLOW_THREADS
9821 res = renameat(oldfd, opath, newfd, npath);
9822 Py_END_ALLOW_THREADS
9823 Py_DECREF(opathold);
9824 Py_DECREF(opathnew);
9825 if (res < 0)
9826 return posix_error();
9827 Py_RETURN_NONE;
9828}
9829#endif
9830
9831#if HAVE_SYMLINKAT
9832PyDoc_STRVAR(posix_symlinkat__doc__,
9833"symlinkat(src, dstfd, dst)\n\n\
9834Like symlink() but if dst is relative, it is taken as relative to dstfd.\n\
9835If dst is relative and dstfd is the special value AT_FDCWD, then dst\n\
9836is interpreted relative to the current working directory.");
9837
9838static PyObject *
9839posix_symlinkat(PyObject *self, PyObject *args)
9840{
9841 int res, dstfd;
9842 PyObject *osrc, *odst;
9843 char *src, *dst;
9844
9845 if (!PyArg_ParseTuple(args, "O&iO&:symlinkat",
9846 PyUnicode_FSConverter, &osrc, &dstfd, PyUnicode_FSConverter, &odst))
9847 return NULL;
9848 src = PyBytes_AsString(osrc);
9849 dst = PyBytes_AsString(odst);
9850 Py_BEGIN_ALLOW_THREADS
9851 res = symlinkat(src, dstfd, dst);
9852 Py_END_ALLOW_THREADS
9853 Py_DECREF(osrc);
9854 Py_DECREF(odst);
9855 if (res < 0)
9856 return posix_error();
9857 Py_RETURN_NONE;
9858}
9859#endif /* HAVE_SYMLINKAT */
9860
9861#ifdef HAVE_UNLINKAT
9862PyDoc_STRVAR(posix_unlinkat__doc__,
9863"unlinkat(dirfd, path, flags=0)\n\n\
9864Like unlink() but if path is relative, it is taken as relative to dirfd.\n\
9865flags is optional and may be 0 or AT_REMOVEDIR. If AT_REMOVEDIR is\n\
9866specified, unlinkat() behaves like rmdir().\n\
9867If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9868is interpreted relative to the current working directory.");
9869
9870static PyObject *
9871posix_unlinkat(PyObject *self, PyObject *args)
9872{
9873 int dirfd, res, flags = 0;
9874 PyObject *opath;
9875 char *path;
9876
9877 if (!PyArg_ParseTuple(args, "iO&|i:unlinkat",
9878 &dirfd, PyUnicode_FSConverter, &opath, &flags))
9879 return NULL;
9880 path = PyBytes_AsString(opath);
9881 Py_BEGIN_ALLOW_THREADS
9882 res = unlinkat(dirfd, path, flags);
9883 Py_END_ALLOW_THREADS
9884 Py_DECREF(opath);
9885 if (res < 0)
9886 return posix_error();
9887 Py_RETURN_NONE;
9888}
9889#endif
9890
9891#ifdef HAVE_UTIMENSAT
9892PyDoc_STRVAR(posix_utimensat__doc__,
Brian Curtin569b4942011-11-07 16:09:20 -06009893"utimensat(dirfd, path[, atime=(atime_sec, atime_nsec),\n\
9894 mtime=(mtime_sec, mtime_nsec), flags=0])\n\
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009895utimensat(dirfd, path, None, None, flags)\n\n\
9896Updates the timestamps of a file with nanosecond precision. If path is\n\
9897relative, it is taken as relative to dirfd.\n\
Brian Curtin569b4942011-11-07 16:09:20 -06009898If atime and mtime are both None, which is the default, set atime and\n\
9899mtime to the current time.\n\
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009900flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9901If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9902is interpreted relative to the current working directory.\n\
9903If *_nsec is specified as UTIME_NOW, the timestamp is updated to the\n\
9904current time.\n\
9905If *_nsec is specified as UTIME_OMIT, the timestamp is not updated.");
9906
9907static PyObject *
Brian Curtin569b4942011-11-07 16:09:20 -06009908posix_utimensat(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009909{
9910 PyObject *opath;
9911 char *path;
9912 int res, dirfd, flags = 0;
Brian Curtin569b4942011-11-07 16:09:20 -06009913 PyObject *atime = Py_None;
9914 PyObject *mtime = Py_None;
9915
9916 static char *kwlist[] = {"dirfd", "path", "atime", "mtime", "flags", NULL};
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009917
9918 struct timespec buf[2];
9919
Brian Curtin569b4942011-11-07 16:09:20 -06009920 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iO&|OOi:utimensat", kwlist,
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009921 &dirfd, PyUnicode_FSConverter, &opath, &atime, &mtime, &flags))
9922 return NULL;
9923 path = PyBytes_AsString(opath);
9924 if (atime == Py_None && mtime == Py_None) {
9925 /* optional time values not given */
9926 Py_BEGIN_ALLOW_THREADS
9927 res = utimensat(dirfd, path, NULL, flags);
9928 Py_END_ALLOW_THREADS
9929 }
9930 else if (!PyTuple_Check(atime) || PyTuple_Size(atime) != 2) {
9931 PyErr_SetString(PyExc_TypeError,
9932 "utimensat() arg 3 must be a tuple (atime_sec, atime_nsec)");
9933 Py_DECREF(opath);
9934 return NULL;
9935 }
9936 else if (!PyTuple_Check(mtime) || PyTuple_Size(mtime) != 2) {
9937 PyErr_SetString(PyExc_TypeError,
9938 "utimensat() arg 4 must be a tuple (mtime_sec, mtime_nsec)");
9939 Py_DECREF(opath);
9940 return NULL;
9941 }
9942 else {
9943 if (!PyArg_ParseTuple(atime, "ll:utimensat",
9944 &(buf[0].tv_sec), &(buf[0].tv_nsec))) {
9945 Py_DECREF(opath);
9946 return NULL;
9947 }
9948 if (!PyArg_ParseTuple(mtime, "ll:utimensat",
9949 &(buf[1].tv_sec), &(buf[1].tv_nsec))) {
9950 Py_DECREF(opath);
9951 return NULL;
9952 }
9953 Py_BEGIN_ALLOW_THREADS
9954 res = utimensat(dirfd, path, buf, flags);
9955 Py_END_ALLOW_THREADS
9956 }
9957 Py_DECREF(opath);
9958 if (res < 0) {
9959 return posix_error();
9960 }
9961 Py_RETURN_NONE;
9962}
9963#endif
9964
9965#ifdef HAVE_MKFIFOAT
9966PyDoc_STRVAR(posix_mkfifoat__doc__,
9967"mkfifoat(dirfd, path, mode=0o666)\n\n\
9968Like mkfifo() but if path is relative, it is taken as relative to dirfd.\n\
9969If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9970is interpreted relative to the current working directory.");
9971
9972static PyObject *
9973posix_mkfifoat(PyObject *self, PyObject *args)
9974{
9975 PyObject *opath;
9976 char *filename;
9977 int mode = 0666;
9978 int res, dirfd;
9979 if (!PyArg_ParseTuple(args, "iO&|i:mkfifoat",
9980 &dirfd, PyUnicode_FSConverter, &opath, &mode))
9981 return NULL;
9982 filename = PyBytes_AS_STRING(opath);
9983 Py_BEGIN_ALLOW_THREADS
9984 res = mkfifoat(dirfd, filename, mode);
9985 Py_END_ALLOW_THREADS
9986 Py_DECREF(opath);
9987 if (res < 0)
9988 return posix_error();
9989 Py_RETURN_NONE;
9990}
9991#endif
9992
Benjamin Peterson9428d532011-09-14 11:45:52 -04009993#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -04009994
9995static int
9996try_getxattr(const char *path, const char *name,
9997 ssize_t (*get)(const char *, const char *, void *, size_t),
9998 Py_ssize_t buf_size, PyObject **res)
9999{
10000 PyObject *value;
10001 Py_ssize_t len;
10002
10003 assert(buf_size <= XATTR_SIZE_MAX);
10004 value = PyBytes_FromStringAndSize(NULL, buf_size);
10005 if (!value)
10006 return 0;
10007 Py_BEGIN_ALLOW_THREADS;
10008 len = get(path, name, PyBytes_AS_STRING(value), buf_size);
10009 Py_END_ALLOW_THREADS;
10010 if (len < 0) {
10011 Py_DECREF(value);
10012 if (errno == ERANGE) {
10013 value = NULL;
10014 }
10015 else {
10016 posix_error();
10017 return 0;
10018 }
10019 }
10020 else if (len != buf_size) {
10021 /* Can only shrink. */
10022 _PyBytes_Resize(&value, len);
10023 }
10024 *res = value;
10025 return 1;
10026}
10027
10028static PyObject *
10029getxattr_common(const char *path, PyObject *name_obj,
10030 ssize_t (*get)(const char *, const char *, void *, size_t))
10031{
10032 PyObject *value;
10033 const char *name = PyBytes_AS_STRING(name_obj);
10034
10035 /* Try a small value first. */
10036 if (!try_getxattr(path, name, get, 128, &value))
10037 return NULL;
10038 if (value)
10039 return value;
10040 /* Now the maximum possible one. */
10041 if (!try_getxattr(path, name, get, XATTR_SIZE_MAX, &value))
10042 return NULL;
10043 assert(value);
10044 return value;
10045}
10046
10047PyDoc_STRVAR(posix_getxattr__doc__,
10048"getxattr(path, attr) -> value\n\n\
10049Return the value of extended attribute *name* on *path*.");
10050
10051static PyObject *
10052posix_getxattr(PyObject *self, PyObject *args)
10053{
10054 PyObject *path, *res, *name;
10055
10056 if (!PyArg_ParseTuple(args, "O&O&:getxattr", PyUnicode_FSConverter, &path,
10057 PyUnicode_FSConverter, &name))
10058 return NULL;
10059 res = getxattr_common(PyBytes_AS_STRING(path), name, getxattr);
10060 Py_DECREF(path);
10061 Py_DECREF(name);
10062 return res;
10063}
10064
10065PyDoc_STRVAR(posix_lgetxattr__doc__,
10066"lgetxattr(path, attr) -> value\n\n\
10067Like getxattr but don't follow symlinks.");
10068
10069static PyObject *
10070posix_lgetxattr(PyObject *self, PyObject *args)
10071{
10072 PyObject *path, *res, *name;
10073
10074 if (!PyArg_ParseTuple(args, "O&O&:lgetxattr", PyUnicode_FSConverter, &path,
10075 PyUnicode_FSConverter, &name))
10076 return NULL;
10077 res = getxattr_common(PyBytes_AS_STRING(path), name, lgetxattr);
10078 Py_DECREF(path);
10079 Py_DECREF(name);
10080 return res;
10081}
10082
10083static ssize_t
10084wrap_fgetxattr(const char *path, const char *name, void *value, size_t size)
10085{
10086 /* Hack to share code. */
10087 return fgetxattr((int)(Py_uintptr_t)path, name, value, size);
10088}
10089
10090PyDoc_STRVAR(posix_fgetxattr__doc__,
10091"fgetxattr(fd, attr) -> value\n\n\
10092Like getxattr but operate on a fd instead of a path.");
10093
10094static PyObject *
10095posix_fgetxattr(PyObject *self, PyObject *args)
10096{
10097 PyObject *res, *name;
10098 int fd;
10099
10100 if (!PyArg_ParseTuple(args, "iO&:fgetxattr", &fd, PyUnicode_FSConverter, &name))
10101 return NULL;
10102 res = getxattr_common((const char *)(Py_uintptr_t)fd, name, wrap_fgetxattr);
10103 Py_DECREF(name);
10104 return res;
10105}
10106
10107PyDoc_STRVAR(posix_setxattr__doc__,
10108"setxattr(path, attr, value, flags=0)\n\n\
10109Set extended attribute *attr* on *path* to *value*.");
10110
10111static PyObject *
10112posix_setxattr(PyObject *self, PyObject *args)
10113{
10114 PyObject *path, *name;
10115 Py_buffer data;
10116 int flags = 0, err;
10117
10118 if (!PyArg_ParseTuple(args, "O&O&y*|i:setxattr", PyUnicode_FSConverter,
10119 &path, PyUnicode_FSConverter, &name, &data, &flags))
10120 return NULL;
10121 Py_BEGIN_ALLOW_THREADS;
10122 err = setxattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name),
10123 data.buf, data.len, flags);
10124 Py_END_ALLOW_THREADS;
10125 Py_DECREF(path);
10126 Py_DECREF(name);
10127 PyBuffer_Release(&data);
10128 if (err)
10129 return posix_error();
10130 Py_RETURN_NONE;
10131}
10132
10133PyDoc_STRVAR(posix_lsetxattr__doc__,
10134"lsetxattr(path, attr, value, flags=0)\n\n\
10135Like setxattr but don't follow symlinks.");
10136
10137static PyObject *
10138posix_lsetxattr(PyObject *self, PyObject *args)
10139{
10140 PyObject *path, *name;
10141 Py_buffer data;
10142 int flags = 0, err;
10143
10144 if (!PyArg_ParseTuple(args, "O&O&y*|i:lsetxattr", PyUnicode_FSConverter,
10145 &path, PyUnicode_FSConverter, &name, &data, &flags))
10146 return NULL;
10147 Py_BEGIN_ALLOW_THREADS;
10148 err = lsetxattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name),
10149 data.buf, data.len, flags);
10150 Py_END_ALLOW_THREADS;
10151 Py_DECREF(path);
10152 Py_DECREF(name);
10153 PyBuffer_Release(&data);
10154 if (err)
10155 return posix_error();
10156 Py_RETURN_NONE;
10157}
10158
10159PyDoc_STRVAR(posix_fsetxattr__doc__,
10160"fsetxattr(fd, attr, value, flags=0)\n\n\
10161Like setxattr but operates on *fd* instead of a path.");
10162
10163static PyObject *
10164posix_fsetxattr(PyObject *self, PyObject *args)
10165{
10166 Py_buffer data;
10167 const char *name;
10168 int fd, flags = 0, err;
10169
10170 if (!PyArg_ParseTuple(args, "iO&y*|i:fsetxattr", &fd, PyUnicode_FSConverter,
10171 &name, &data, &flags))
10172 return NULL;
10173 Py_BEGIN_ALLOW_THREADS;
10174 err = fsetxattr(fd, PyBytes_AS_STRING(name), data.buf, data.len, flags);
10175 Py_END_ALLOW_THREADS;
10176 Py_DECREF(name);
10177 PyBuffer_Release(&data);
10178 if (err)
10179 return posix_error();
10180 Py_RETURN_NONE;
10181}
10182
10183PyDoc_STRVAR(posix_removexattr__doc__,
10184"removexattr(path, attr)\n\n\
10185Remove extended attribute *attr* on *path*.");
10186
10187static PyObject *
10188posix_removexattr(PyObject *self, PyObject *args)
10189{
10190 PyObject *path, *name;
10191 int err;
10192
10193 if (!PyArg_ParseTuple(args, "O&O&:removexattr", PyUnicode_FSConverter, &path,
10194 PyUnicode_FSConverter, &name))
10195 return NULL;
10196 Py_BEGIN_ALLOW_THREADS;
10197 err = removexattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name));
10198 Py_END_ALLOW_THREADS;
10199 Py_DECREF(path);
10200 Py_DECREF(name);
10201 if (err)
10202 return posix_error();
10203 Py_RETURN_NONE;
10204}
10205
10206PyDoc_STRVAR(posix_lremovexattr__doc__,
10207"lremovexattr(path, attr)\n\n\
10208Like removexattr but don't follow symlinks.");
10209
10210static PyObject *
10211posix_lremovexattr(PyObject *self, PyObject *args)
10212{
10213 PyObject *path, *name;
10214 int err;
10215
10216 if (!PyArg_ParseTuple(args, "O&O&:lremovexattr", PyUnicode_FSConverter, &path,
10217 PyUnicode_FSConverter, &name))
10218 return NULL;
10219 Py_BEGIN_ALLOW_THREADS;
10220 err = lremovexattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name));
10221 Py_END_ALLOW_THREADS;
10222 Py_DECREF(path);
10223 Py_DECREF(name);
10224 if (err)
10225 return posix_error();
10226 Py_RETURN_NONE;
10227}
10228
10229PyDoc_STRVAR(posix_fremovexattr__doc__,
10230"fremovexattr(fd, attr)\n\n\
10231Like removexattr but operates on a file descriptor.");
10232
10233static PyObject *
10234posix_fremovexattr(PyObject *self, PyObject *args)
10235{
10236 PyObject *name;
10237 int fd, err;
10238
10239 if (!PyArg_ParseTuple(args, "iO&:fremovexattr", &fd,
10240 PyUnicode_FSConverter, &name))
10241 return NULL;
10242 Py_BEGIN_ALLOW_THREADS;
10243 err = fremovexattr(fd, PyBytes_AS_STRING(name));
10244 Py_END_ALLOW_THREADS;
10245 Py_DECREF(name);
10246 if (err)
10247 return posix_error();
10248 Py_RETURN_NONE;
10249}
10250
10251static Py_ssize_t
10252try_listxattr(const char *path, ssize_t (*list)(const char *, char *, size_t),
10253 Py_ssize_t buf_size, char **buf)
10254{
10255 Py_ssize_t len;
10256
10257 *buf = PyMem_MALLOC(buf_size);
10258 if (!*buf) {
10259 PyErr_NoMemory();
10260 return -1;
10261 }
10262 Py_BEGIN_ALLOW_THREADS;
10263 len = list(path, *buf, buf_size);
10264 Py_END_ALLOW_THREADS;
10265 if (len < 0) {
10266 PyMem_FREE(*buf);
10267 if (errno != ERANGE)
10268 posix_error();
10269 return -1;
10270 }
10271 return len;
10272}
10273
10274static PyObject *
10275listxattr_common(const char *path, ssize_t (*list)(const char *, char *, size_t))
10276{
10277 PyObject *res, *attr;
10278 Py_ssize_t len, err, start, i;
10279 char *buf;
10280
10281 len = try_listxattr(path, list, 256, &buf);
10282 if (len < 0) {
10283 if (PyErr_Occurred())
10284 return NULL;
10285 len = try_listxattr(path, list, XATTR_LIST_MAX, &buf);
10286 if (len < 0)
10287 return NULL;
10288 }
10289 res = PyList_New(0);
10290 if (!res) {
10291 PyMem_FREE(buf);
10292 return NULL;
10293 }
10294 for (start = i = 0; i < len; i++) {
10295 if (!buf[i]) {
10296 attr = PyUnicode_DecodeFSDefaultAndSize(&buf[start], i - start);
10297 if (!attr) {
10298 Py_DECREF(res);
10299 PyMem_FREE(buf);
10300 return NULL;
10301 }
10302 err = PyList_Append(res, attr);
10303 Py_DECREF(attr);
10304 if (err) {
10305 Py_DECREF(res);
10306 PyMem_FREE(buf);
10307 return NULL;
10308 }
10309 start = i + 1;
10310 }
10311 }
10312 PyMem_FREE(buf);
10313 return res;
10314}
10315
10316PyDoc_STRVAR(posix_listxattr__doc__,
10317"listxattr(path)\n\n\
10318Return a list of extended attributes on *path*.");
10319
10320static PyObject *
10321posix_listxattr(PyObject *self, PyObject *args)
10322{
10323 PyObject *path, *res;
10324
10325 if (!PyArg_ParseTuple(args, "O&:listxattr", PyUnicode_FSConverter, &path))
10326 return NULL;
10327 res = listxattr_common(PyBytes_AS_STRING(path), listxattr);
10328 Py_DECREF(path);
10329 return res;
10330}
10331
10332PyDoc_STRVAR(posix_llistxattr__doc__,
10333"llistxattr(path)\n\n\
10334Like listxattr but don't follow symlinks..");
10335
10336static PyObject *
10337posix_llistxattr(PyObject *self, PyObject *args)
10338{
10339 PyObject *path, *res;
10340
10341 if (!PyArg_ParseTuple(args, "O&:llistxattr", PyUnicode_FSConverter, &path))
10342 return NULL;
10343 res = listxattr_common(PyBytes_AS_STRING(path), llistxattr);
10344 Py_DECREF(path);
10345 return res;
10346}
10347
10348static ssize_t
10349wrap_flistxattr(const char *path, char *buf, size_t len)
10350{
10351 /* Hack to share code. */
10352 return flistxattr((int)(Py_uintptr_t)path, buf, len);
10353}
10354
10355PyDoc_STRVAR(posix_flistxattr__doc__,
10356"flistxattr(path)\n\n\
10357Like flistxattr but operates on a file descriptor.");
10358
10359static PyObject *
10360posix_flistxattr(PyObject *self, PyObject *args)
10361{
10362 long fd;
10363
10364 if (!PyArg_ParseTuple(args, "i:flistxattr", &fd))
10365 return NULL;
10366 return listxattr_common((const char *)(Py_uintptr_t)fd, wrap_flistxattr);
10367}
10368
Benjamin Peterson9428d532011-09-14 11:45:52 -040010369#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010370
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010371
Georg Brandl2fb477c2012-02-21 00:33:36 +010010372PyDoc_STRVAR(posix_urandom__doc__,
10373"urandom(n) -> str\n\n\
10374Return n random bytes suitable for cryptographic use.");
10375
10376static PyObject *
10377posix_urandom(PyObject *self, PyObject *args)
10378{
10379 Py_ssize_t size;
10380 PyObject *result;
10381 int ret;
10382
10383 /* Read arguments */
10384 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10385 return NULL;
10386 if (size < 0)
10387 return PyErr_Format(PyExc_ValueError,
10388 "negative argument not allowed");
10389 result = PyBytes_FromStringAndSize(NULL, size);
10390 if (result == NULL)
10391 return NULL;
10392
10393 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10394 PyBytes_GET_SIZE(result));
10395 if (ret == -1) {
10396 Py_DECREF(result);
10397 return NULL;
10398 }
10399 return result;
10400}
10401
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010402/* Terminal size querying */
10403
10404static PyTypeObject TerminalSizeType;
10405
10406PyDoc_STRVAR(TerminalSize_docstring,
10407 "A tuple of (columns, lines) for holding terminal window size");
10408
10409static PyStructSequence_Field TerminalSize_fields[] = {
10410 {"columns", "width of the terminal window in characters"},
10411 {"lines", "height of the terminal window in characters"},
10412 {NULL, NULL}
10413};
10414
10415static PyStructSequence_Desc TerminalSize_desc = {
10416 "os.terminal_size",
10417 TerminalSize_docstring,
10418 TerminalSize_fields,
10419 2,
10420};
10421
10422#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10423PyDoc_STRVAR(termsize__doc__,
10424 "Return the size of the terminal window as (columns, lines).\n" \
10425 "\n" \
10426 "The optional argument fd (default standard output) specifies\n" \
10427 "which file descriptor should be queried.\n" \
10428 "\n" \
10429 "If the file descriptor is not connected to a terminal, an OSError\n" \
10430 "is thrown.\n" \
10431 "\n" \
10432 "This function will only be defined if an implementation is\n" \
10433 "available for this system.\n" \
10434 "\n" \
10435 "shutil.get_terminal_size is the high-level function which should \n" \
10436 "normally be used, os.get_terminal_size is the low-level implementation.");
10437
10438static PyObject*
10439get_terminal_size(PyObject *self, PyObject *args)
10440{
10441 int columns, lines;
10442 PyObject *termsize;
10443
10444 int fd = fileno(stdout);
10445 /* Under some conditions stdout may not be connected and
10446 * fileno(stdout) may point to an invalid file descriptor. For example
10447 * GUI apps don't have valid standard streams by default.
10448 *
10449 * If this happens, and the optional fd argument is not present,
10450 * the ioctl below will fail returning EBADF. This is what we want.
10451 */
10452
10453 if (!PyArg_ParseTuple(args, "|i", &fd))
10454 return NULL;
10455
10456#ifdef TERMSIZE_USE_IOCTL
10457 {
10458 struct winsize w;
10459 if (ioctl(fd, TIOCGWINSZ, &w))
10460 return PyErr_SetFromErrno(PyExc_OSError);
10461 columns = w.ws_col;
10462 lines = w.ws_row;
10463 }
10464#endif /* TERMSIZE_USE_IOCTL */
10465
10466#ifdef TERMSIZE_USE_CONIO
10467 {
10468 DWORD nhandle;
10469 HANDLE handle;
10470 CONSOLE_SCREEN_BUFFER_INFO csbi;
10471 switch (fd) {
10472 case 0: nhandle = STD_INPUT_HANDLE;
10473 break;
10474 case 1: nhandle = STD_OUTPUT_HANDLE;
10475 break;
10476 case 2: nhandle = STD_ERROR_HANDLE;
10477 break;
10478 default:
10479 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10480 }
10481 handle = GetStdHandle(nhandle);
10482 if (handle == NULL)
10483 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10484 if (handle == INVALID_HANDLE_VALUE)
10485 return PyErr_SetFromWindowsErr(0);
10486
10487 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10488 return PyErr_SetFromWindowsErr(0);
10489
10490 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10491 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10492 }
10493#endif /* TERMSIZE_USE_CONIO */
10494
10495 termsize = PyStructSequence_New(&TerminalSizeType);
10496 if (termsize == NULL)
10497 return NULL;
10498 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10499 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10500 if (PyErr_Occurred()) {
10501 Py_DECREF(termsize);
10502 return NULL;
10503 }
10504 return termsize;
10505}
10506#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10507
10508
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010509static PyMethodDef posix_methods[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +000010510 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010511#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010512 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010513#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010514 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010515#ifdef HAVE_CHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010516 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010517#endif /* HAVE_CHFLAGS */
Victor Stinner8c62be82010-05-06 00:08:46 +000010518 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010519#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010520 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010521#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010522#ifdef HAVE_CHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010523 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010524#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010525#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010526 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010527#endif /* HAVE_LCHMOD */
10528#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010529 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010530#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010531#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010532 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010533#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010534#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010535 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010536#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010537#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010538 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010539#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010540#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010541 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010542#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010543#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010544 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10545 METH_NOARGS, posix_getcwd__doc__},
10546 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10547 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010548#endif
10549#ifdef HAVE_LINK
Victor Stinner8c62be82010-05-06 00:08:46 +000010550 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010551#endif /* HAVE_LINK */
Victor Stinner8c62be82010-05-06 00:08:46 +000010552 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
Antoine Pitrou8250e232011-02-25 23:41:16 +000010553#ifdef HAVE_FDOPENDIR
Charles-François Natali77940902012-02-06 19:54:48 +010010554 {"flistdir", posix_flistdir, METH_VARARGS, posix_flistdir__doc__},
Antoine Pitrou8250e232011-02-25 23:41:16 +000010555#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010010556 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010557 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010558#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010559 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000010560#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010561#ifdef HAVE_GETPRIORITY
10562 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10563#endif /* HAVE_GETPRIORITY */
10564#ifdef HAVE_SETPRIORITY
10565 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10566#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010567#ifdef HAVE_READLINK
Victor Stinner8c62be82010-05-06 00:08:46 +000010568 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010569#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010570#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +000010571 {"readlink", win_readlink, METH_VARARGS, win_readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010572#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +000010573 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
Antoine Pitrouf3b2d882012-01-30 22:08:52 +010010574 {"replace", posix_replace, METH_VARARGS, posix_replace__doc__},
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +000010575 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
Victor Stinner4195b5c2012-02-08 23:03:19 +010010576 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010577 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Brian Curtin52173d42010-12-02 18:29:18 +000010578#if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +000010579 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010580#endif /* HAVE_SYMLINK */
Brian Curtin52173d42010-12-02 18:29:18 +000010581#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000010582 {"symlink", (PyCFunction)win_symlink, METH_VARARGS | METH_KEYWORDS,
Brian Curtin52173d42010-12-02 18:29:18 +000010583 win_symlink__doc__},
10584#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossum85e3b011991-06-03 12:42:10 +000010585#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010586 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010587#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010588 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010589#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010590 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010591#endif /* HAVE_UNAME */
Victor Stinner8c62be82010-05-06 00:08:46 +000010592 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
10593 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
10594 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010595#ifdef HAVE_FUTIMES
10596 {"futimes", posix_futimes, METH_VARARGS, posix_futimes__doc__},
10597#endif
10598#ifdef HAVE_LUTIMES
10599 {"lutimes", posix_lutimes, METH_VARARGS, posix_lutimes__doc__},
10600#endif
10601#ifdef HAVE_FUTIMENS
10602 {"futimens", posix_futimens, METH_VARARGS, posix_futimens__doc__},
10603#endif
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000010604#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010605 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010606#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010607 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010608#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010609 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
10610 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010611#endif /* HAVE_EXECV */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010612#ifdef HAVE_FEXECVE
10613 {"fexecve", posix_fexecve, METH_VARARGS, posix_fexecve__doc__},
10614#endif
Guido van Rossuma1065681999-01-25 23:20:23 +000010615#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010616 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10617 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010618#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000010619 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
10620 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010621#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +000010622#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010623#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010624 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010625#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010626#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010627 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010628#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010629#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010630#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010631 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
10632 {"sched_get_priority_min", posix_sched_get_priority_min, METH_VARARGS, posix_sched_get_priority_min__doc__},
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010633#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010634#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010635 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010636#endif
10637#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010638 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010639#endif
10640#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010641 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010642#endif
10643#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010644 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010645#endif
10646#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010647 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010648#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010649 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050010650#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010651 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
10652 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
10653#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010654#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010655#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000010656 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010657#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000010658#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010659 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000010660#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000010661#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010662 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000010663#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010664#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010665 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000010666#endif /* HAVE_GETEUID */
10667#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010668 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010669#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020010670#ifdef HAVE_GETGROUPLIST
10671 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
10672#endif
Fred Drakec9680921999-12-13 16:37:25 +000010673#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010674 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010675#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010676 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010677#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010678 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010679#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010680#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010681 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010682#endif /* HAVE_GETPPID */
10683#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010684 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010685#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000010686#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010687 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000010688#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000010689#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000010690 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010691#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010692#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000010693 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010694#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000010695#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010696 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000010697#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000010698#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010699 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
10700 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Brian Curtin1b9df392010-11-24 20:24:31 +000010701 {"link", win32_link, METH_VARARGS, win32_link__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000010702#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010703#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010704 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010705#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010706#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010707 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010708#endif /* HAVE_SETEUID */
10709#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010710 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010711#endif /* HAVE_SETEGID */
10712#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010713 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010714#endif /* HAVE_SETREUID */
10715#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010716 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010717#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010718#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010719 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010720#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010721#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010722 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010723#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000010724#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010725 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000010726#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000010727#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010728 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000010729#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010730#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010731 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010732#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010733#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010734 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010735#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010736#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010010737 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010738#endif /* HAVE_WAIT3 */
10739#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010010740 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010741#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010742#if defined(HAVE_WAITID) && !defined(__APPLE__)
10743 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
10744#endif
Tim Petersab034fa2002-02-01 11:27:43 +000010745#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010746 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010747#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010748#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010749 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010750#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010751#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010752 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010753#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010754#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010755 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010756#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010757#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010758 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010759#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010760#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010761 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010762#endif /* HAVE_TCSETPGRP */
Victor Stinner8c62be82010-05-06 00:08:46 +000010763 {"open", posix_open, METH_VARARGS, posix_open__doc__},
10764 {"close", posix_close, METH_VARARGS, posix_close__doc__},
10765 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
10766 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
10767 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
10768 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010769#ifdef HAVE_LOCKF
10770 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
10771#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010772 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
10773 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010774#ifdef HAVE_READV
10775 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
10776#endif
10777#ifdef HAVE_PREAD
10778 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
10779#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010780 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010781#ifdef HAVE_WRITEV
10782 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
10783#endif
10784#ifdef HAVE_PWRITE
10785 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
10786#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000010787#ifdef HAVE_SENDFILE
10788 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
10789 posix_sendfile__doc__},
10790#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010010791 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010792 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010793#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010794 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010795#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010796#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020010797 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010798#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010799#ifdef HAVE_MKFIFO
Victor Stinner8c62be82010-05-06 00:08:46 +000010800 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010801#endif
Neal Norwitz11690112002-07-30 01:08:28 +000010802#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinner8c62be82010-05-06 00:08:46 +000010803 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000010804#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010805#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000010806 {"major", posix_major, METH_VARARGS, posix_major__doc__},
10807 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
10808 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010809#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010810#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000010811 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010812#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010813#ifdef HAVE_TRUNCATE
10814 {"truncate", posix_truncate, METH_VARARGS, posix_truncate__doc__},
10815#endif
10816#ifdef HAVE_POSIX_FALLOCATE
10817 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
10818#endif
10819#ifdef HAVE_POSIX_FADVISE
10820 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
10821#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010822#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010823 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010824#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010825#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010826 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000010827#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010828 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010829#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000010830 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010831#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010832#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010833 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010834#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010835#ifdef HAVE_SYNC
10836 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
10837#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010838#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010839 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010840#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000010841#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010842#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000010843 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000010844#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010845#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000010846 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010847#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000010848#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000010849 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010850#endif /* WIFSTOPPED */
10851#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000010852 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010853#endif /* WIFSIGNALED */
10854#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000010855 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010856#endif /* WIFEXITED */
10857#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000010858 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010859#endif /* WEXITSTATUS */
10860#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010861 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010862#endif /* WTERMSIG */
10863#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010864 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010865#endif /* WSTOPSIG */
10866#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000010867#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000010868 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010869#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000010870#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000010871 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010872#endif
Fred Drakec9680921999-12-13 16:37:25 +000010873#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000010874 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010875#endif
10876#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010877 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010878#endif
10879#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010880 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010881#endif
10882#ifdef HAVE_PATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010883 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010884#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010885 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010886#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010887 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000010888 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +000010889 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050010890 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010891 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000010892#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000010893#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000010894 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000010895#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010010896 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010897#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010898 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010899#endif
10900#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010901 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010902#endif
10903#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010904 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010905#endif
10906#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010907 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010908#endif
10909
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010910/* posix *at family of functions */
10911#ifdef HAVE_FACCESSAT
10912 {"faccessat", posix_faccessat, METH_VARARGS, posix_faccessat__doc__},
10913#endif
10914#ifdef HAVE_FCHMODAT
10915 {"fchmodat", posix_fchmodat, METH_VARARGS, posix_fchmodat__doc__},
10916#endif /* HAVE_FCHMODAT */
10917#ifdef HAVE_FCHOWNAT
10918 {"fchownat", posix_fchownat, METH_VARARGS, posix_fchownat__doc__},
10919#endif /* HAVE_FCHOWNAT */
10920#ifdef HAVE_FSTATAT
Victor Stinner4195b5c2012-02-08 23:03:19 +010010921 {"fstatat", posix_fstatat, METH_VARARGS, posix_fstatat__doc__},
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010922#endif
10923#ifdef HAVE_FUTIMESAT
10924 {"futimesat", posix_futimesat, METH_VARARGS, posix_futimesat__doc__},
10925#endif
10926#ifdef HAVE_LINKAT
10927 {"linkat", posix_linkat, METH_VARARGS, posix_linkat__doc__},
10928#endif /* HAVE_LINKAT */
10929#ifdef HAVE_MKDIRAT
10930 {"mkdirat", posix_mkdirat, METH_VARARGS, posix_mkdirat__doc__},
10931#endif
10932#if defined(HAVE_MKNODAT) && defined(HAVE_MAKEDEV)
10933 {"mknodat", posix_mknodat, METH_VARARGS, posix_mknodat__doc__},
10934#endif
10935#ifdef HAVE_OPENAT
10936 {"openat", posix_openat, METH_VARARGS, posix_openat__doc__},
10937#endif
10938#ifdef HAVE_READLINKAT
10939 {"readlinkat", posix_readlinkat, METH_VARARGS, posix_readlinkat__doc__},
10940#endif /* HAVE_READLINKAT */
10941#ifdef HAVE_RENAMEAT
10942 {"renameat", posix_renameat, METH_VARARGS, posix_renameat__doc__},
10943#endif
10944#if HAVE_SYMLINKAT
10945 {"symlinkat", posix_symlinkat, METH_VARARGS, posix_symlinkat__doc__},
10946#endif /* HAVE_SYMLINKAT */
10947#ifdef HAVE_UNLINKAT
10948 {"unlinkat", posix_unlinkat, METH_VARARGS, posix_unlinkat__doc__},
10949#endif
10950#ifdef HAVE_UTIMENSAT
Jesus Cead03a4912011-11-08 17:28:04 +010010951 {"utimensat", (PyCFunction)posix_utimensat,
10952 METH_VARARGS | METH_KEYWORDS,
Brian Curtin569b4942011-11-07 16:09:20 -060010953 posix_utimensat__doc__},
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010954#endif
10955#ifdef HAVE_MKFIFOAT
10956 {"mkfifoat", posix_mkfifoat, METH_VARARGS, posix_mkfifoat__doc__},
10957#endif
Benjamin Peterson9428d532011-09-14 11:45:52 -040010958#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010959 {"setxattr", posix_setxattr, METH_VARARGS, posix_setxattr__doc__},
10960 {"lsetxattr", posix_lsetxattr, METH_VARARGS, posix_lsetxattr__doc__},
10961 {"fsetxattr", posix_fsetxattr, METH_VARARGS, posix_fsetxattr__doc__},
10962 {"getxattr", posix_getxattr, METH_VARARGS, posix_getxattr__doc__},
10963 {"lgetxattr", posix_lgetxattr, METH_VARARGS, posix_lgetxattr__doc__},
10964 {"fgetxattr", posix_fgetxattr, METH_VARARGS, posix_fgetxattr__doc__},
10965 {"removexattr", posix_removexattr, METH_VARARGS, posix_removexattr__doc__},
10966 {"lremovexattr", posix_lremovexattr, METH_VARARGS, posix_lremovexattr__doc__},
10967 {"fremovexattr", posix_fremovexattr, METH_VARARGS, posix_fremovexattr__doc__},
10968 {"listxattr", posix_listxattr, METH_VARARGS, posix_listxattr__doc__},
10969 {"llistxattr", posix_llistxattr, METH_VARARGS, posix_llistxattr__doc__},
10970 {"flistxattr", posix_flistxattr, METH_VARARGS, posix_flistxattr__doc__},
10971#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010972#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10973 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
10974#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010975 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010976};
10977
10978
Barry Warsaw4a342091996-12-19 23:50:02 +000010979static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010980ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000010981{
Victor Stinner8c62be82010-05-06 00:08:46 +000010982 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000010983}
10984
Guido van Rossumd48f2521997-12-05 22:19:34 +000010985#if defined(PYOS_OS2)
10986/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +000010987static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +000010988{
10989 APIRET rc;
10990 ULONG values[QSV_MAX+1];
10991 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +000010992 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +000010993
10994 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +000010995 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +000010996 Py_END_ALLOW_THREADS
10997
10998 if (rc != NO_ERROR) {
10999 os2_error(rc);
11000 return -1;
11001 }
11002
Fred Drake4d1e64b2002-04-15 19:40:07 +000011003 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
11004 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
11005 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
11006 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
11007 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
11008 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
11009 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011010
11011 switch (values[QSV_VERSION_MINOR]) {
11012 case 0: ver = "2.00"; break;
11013 case 10: ver = "2.10"; break;
11014 case 11: ver = "2.11"; break;
11015 case 30: ver = "3.00"; break;
11016 case 40: ver = "4.00"; break;
11017 case 50: ver = "5.00"; break;
11018 default:
Tim Peters885d4572001-11-28 20:27:42 +000011019 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +000011020 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +000011021 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011022 ver = &tmp[0];
11023 }
11024
11025 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011026 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011027 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011028
11029 /* Add Indicator of Which Drive was Used to Boot the System */
11030 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
11031 tmp[1] = ':';
11032 tmp[2] = '\0';
11033
Fred Drake4d1e64b2002-04-15 19:40:07 +000011034 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011035}
11036#endif
11037
Brian Curtin52173d42010-12-02 18:29:18 +000011038#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011039static int
Brian Curtin52173d42010-12-02 18:29:18 +000011040enable_symlink()
11041{
11042 HANDLE tok;
11043 TOKEN_PRIVILEGES tok_priv;
11044 LUID luid;
11045 int meth_idx = 0;
11046
11047 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011048 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011049
11050 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011051 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011052
11053 tok_priv.PrivilegeCount = 1;
11054 tok_priv.Privileges[0].Luid = luid;
11055 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11056
11057 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11058 sizeof(TOKEN_PRIVILEGES),
11059 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011060 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011061
Brian Curtin3b4499c2010-12-28 14:31:47 +000011062 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11063 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011064}
11065#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11066
Barry Warsaw4a342091996-12-19 23:50:02 +000011067static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011068all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000011069{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011070#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011071 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011072#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011073#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011074 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011075#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011076#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011077 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011078#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011079#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011080 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011081#endif
Fred Drakec9680921999-12-13 16:37:25 +000011082#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011083 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011084#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011085#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011086 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011087#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011088#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011089 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011090#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011091#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000011092 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011093#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011094#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000011095 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011096#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011097#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011098 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011099#endif
11100#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011101 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011102#endif
11103#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000011104 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011105#endif
11106#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000011107 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011108#endif
11109#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011110 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011111#endif
11112#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000011113 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011114#endif
11115#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011116 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011117#endif
11118#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011119 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011120#endif
11121#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011122 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011123#endif
11124#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011125 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011126#endif
11127#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011128 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011129#endif
11130#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000011131 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011132#endif
11133#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011134 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011135#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011136#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011137 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011138#endif
11139#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000011140 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011141#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011142#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011143 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011144#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011145#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011146 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011147#endif
11148#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011149 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011150#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011151#ifdef PRIO_PROCESS
11152 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
11153#endif
11154#ifdef PRIO_PGRP
11155 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
11156#endif
11157#ifdef PRIO_USER
11158 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
11159#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011160#ifdef O_CLOEXEC
11161 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
11162#endif
Antoine Pitrouf65132d2011-02-25 23:25:17 +000011163/* posix - constants for *at functions */
11164#ifdef AT_SYMLINK_NOFOLLOW
11165 if (ins(d, "AT_SYMLINK_NOFOLLOW", (long)AT_SYMLINK_NOFOLLOW)) return -1;
11166#endif
11167#ifdef AT_EACCESS
11168 if (ins(d, "AT_EACCESS", (long)AT_EACCESS)) return -1;
11169#endif
11170#ifdef AT_FDCWD
11171 if (ins(d, "AT_FDCWD", (long)AT_FDCWD)) return -1;
11172#endif
11173#ifdef AT_REMOVEDIR
11174 if (ins(d, "AT_REMOVEDIR", (long)AT_REMOVEDIR)) return -1;
11175#endif
11176#ifdef AT_SYMLINK_FOLLOW
11177 if (ins(d, "AT_SYMLINK_FOLLOW", (long)AT_SYMLINK_FOLLOW)) return -1;
11178#endif
11179#ifdef UTIME_NOW
11180 if (ins(d, "UTIME_NOW", (long)UTIME_NOW)) return -1;
11181#endif
11182#ifdef UTIME_OMIT
11183 if (ins(d, "UTIME_OMIT", (long)UTIME_OMIT)) return -1;
11184#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011185
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011186
Tim Peters5aa91602002-01-30 05:46:57 +000011187/* MS Windows */
11188#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011189 /* Don't inherit in child processes. */
11190 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011191#endif
11192#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011193 /* Optimize for short life (keep in memory). */
11194 /* MS forgot to define this one with a non-underscore form too. */
11195 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011196#endif
11197#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011198 /* Automatically delete when last handle is closed. */
11199 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011200#endif
11201#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011202 /* Optimize for random access. */
11203 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011204#endif
11205#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011206 /* Optimize for sequential access. */
11207 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011208#endif
11209
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011210/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011211#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011212 /* Send a SIGIO signal whenever input or output
11213 becomes available on file descriptor */
11214 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011215#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011216#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011217 /* Direct disk access. */
11218 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011219#endif
11220#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011221 /* Must be a directory. */
11222 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011223#endif
11224#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011225 /* Do not follow links. */
11226 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011227#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011228#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011229 /* Do not update the access time. */
11230 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011231#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011232
Victor Stinner8c62be82010-05-06 00:08:46 +000011233 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011234#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011235 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011236#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011237#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011238 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011239#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011240#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011241 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011242#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011243#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011244 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011245#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011246#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000011247 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011248#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011249#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000011250 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011251#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011252#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011253 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011254#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011255#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000011256 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011257#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011258#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011259 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011260#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011261#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011262 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011263#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011264#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011265 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011266#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011267#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011268 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011269#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011270#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000011271 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011272#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011273#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000011274 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011275#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011276#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011277 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011278#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011279#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011280 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011281#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011282#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000011283 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011284#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011285
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011286 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011287#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011288 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011289#endif /* ST_RDONLY */
11290#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011291 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011292#endif /* ST_NOSUID */
11293
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011294 /* FreeBSD sendfile() constants */
11295#ifdef SF_NODISKIO
11296 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
11297#endif
11298#ifdef SF_MNOWAIT
11299 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
11300#endif
11301#ifdef SF_SYNC
11302 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
11303#endif
11304
Ross Lagerwall7807c352011-03-17 20:20:30 +020011305 /* constants for posix_fadvise */
11306#ifdef POSIX_FADV_NORMAL
11307 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
11308#endif
11309#ifdef POSIX_FADV_SEQUENTIAL
11310 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
11311#endif
11312#ifdef POSIX_FADV_RANDOM
11313 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
11314#endif
11315#ifdef POSIX_FADV_NOREUSE
11316 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
11317#endif
11318#ifdef POSIX_FADV_WILLNEED
11319 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
11320#endif
11321#ifdef POSIX_FADV_DONTNEED
11322 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
11323#endif
11324
11325 /* constants for waitid */
11326#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
11327 if (ins(d, "P_PID", (long)P_PID)) return -1;
11328 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
11329 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
11330#endif
11331#ifdef WEXITED
11332 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
11333#endif
11334#ifdef WNOWAIT
11335 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
11336#endif
11337#ifdef WSTOPPED
11338 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
11339#endif
11340#ifdef CLD_EXITED
11341 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
11342#endif
11343#ifdef CLD_DUMPED
11344 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
11345#endif
11346#ifdef CLD_TRAPPED
11347 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
11348#endif
11349#ifdef CLD_CONTINUED
11350 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
11351#endif
11352
11353 /* constants for lockf */
11354#ifdef F_LOCK
11355 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
11356#endif
11357#ifdef F_TLOCK
11358 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
11359#endif
11360#ifdef F_ULOCK
11361 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
11362#endif
11363#ifdef F_TEST
11364 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
11365#endif
11366
11367 /* constants for futimens */
11368#ifdef UTIME_NOW
11369 if (ins(d, "UTIME_NOW", (long)UTIME_NOW)) return -1;
11370#endif
11371#ifdef UTIME_OMIT
11372 if (ins(d, "UTIME_OMIT", (long)UTIME_OMIT)) return -1;
11373#endif
11374
Guido van Rossum246bc171999-02-01 23:54:31 +000011375#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011376#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +000011377 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
11378 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
11379 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
11380 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
11381 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
11382 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
11383 if (ins(d, "P_PM", (long)P_PM)) return -1;
11384 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
11385 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
11386 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
11387 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
11388 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
11389 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
11390 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
11391 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
11392 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
11393 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
11394 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
11395 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
11396 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011397#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011398 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
11399 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
11400 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
11401 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
11402 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011403#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011404#endif
Guido van Rossum246bc171999-02-01 23:54:31 +000011405
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011406#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011407 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011408 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11409 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11410#ifdef SCHED_SPORADIC
11411 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
11412#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011413#ifdef SCHED_BATCH
11414 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11415#endif
11416#ifdef SCHED_IDLE
11417 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11418#endif
11419#ifdef SCHED_RESET_ON_FORK
11420 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11421#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011422#ifdef SCHED_SYS
11423 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11424#endif
11425#ifdef SCHED_IA
11426 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11427#endif
11428#ifdef SCHED_FSS
11429 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11430#endif
11431#ifdef SCHED_FX
11432 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11433#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011434#endif
11435
Benjamin Peterson9428d532011-09-14 11:45:52 -040011436#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011437 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11438 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11439 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11440#endif
11441
Victor Stinner8b905bd2011-10-25 13:34:04 +020011442#ifdef RTLD_LAZY
11443 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11444#endif
11445#ifdef RTLD_NOW
11446 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11447#endif
11448#ifdef RTLD_GLOBAL
11449 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11450#endif
11451#ifdef RTLD_LOCAL
11452 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11453#endif
11454#ifdef RTLD_NODELETE
11455 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11456#endif
11457#ifdef RTLD_NOLOAD
11458 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11459#endif
11460#ifdef RTLD_DEEPBIND
11461 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11462#endif
11463
Guido van Rossumd48f2521997-12-05 22:19:34 +000011464#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000011465 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011466#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011467 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011468}
11469
11470
Tim Peters5aa91602002-01-30 05:46:57 +000011471#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011472#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011473#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011474
11475#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011476#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011477#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011478
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011479#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011480#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011481#define MODNAME "posix"
11482#endif
11483
Martin v. Löwis1a214512008-06-11 05:26:20 +000011484static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011485 PyModuleDef_HEAD_INIT,
11486 MODNAME,
11487 posix__doc__,
11488 -1,
11489 posix_methods,
11490 NULL,
11491 NULL,
11492 NULL,
11493 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011494};
11495
11496
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011497PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011498INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011499{
Victor Stinner8c62be82010-05-06 00:08:46 +000011500 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +000011501
Brian Curtin52173d42010-12-02 18:29:18 +000011502#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011503 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011504#endif
11505
Victor Stinner8c62be82010-05-06 00:08:46 +000011506 m = PyModule_Create(&posixmodule);
11507 if (m == NULL)
11508 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011509
Victor Stinner8c62be82010-05-06 00:08:46 +000011510 /* Initialize environ dictionary */
11511 v = convertenviron();
11512 Py_XINCREF(v);
11513 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11514 return NULL;
11515 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011516
Victor Stinner8c62be82010-05-06 00:08:46 +000011517 if (all_ins(m))
11518 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011519
Victor Stinner8c62be82010-05-06 00:08:46 +000011520 if (setup_confname_tables(m))
11521 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011522
Victor Stinner8c62be82010-05-06 00:08:46 +000011523 Py_INCREF(PyExc_OSError);
11524 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011525
Benjamin Peterson2740af82011-08-02 17:41:34 -050011526#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011527 if (PyType_Ready(&cpu_set_type) < 0)
11528 return NULL;
11529 Py_INCREF(&cpu_set_type);
11530 PyModule_AddObject(m, "cpu_set", (PyObject *)&cpu_set_type);
Benjamin Peterson2740af82011-08-02 17:41:34 -050011531#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011532
Guido van Rossumb3d39562000-01-31 18:41:26 +000011533#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011534 if (posix_putenv_garbage == NULL)
11535 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011536#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011537
Victor Stinner8c62be82010-05-06 00:08:46 +000011538 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011539#if defined(HAVE_WAITID) && !defined(__APPLE__)
11540 waitid_result_desc.name = MODNAME ".waitid_result";
11541 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
11542#endif
11543
Victor Stinner8c62be82010-05-06 00:08:46 +000011544 stat_result_desc.name = MODNAME ".stat_result";
11545 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11546 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11547 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
11548 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
11549 structseq_new = StatResultType.tp_new;
11550 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011551
Victor Stinner8c62be82010-05-06 00:08:46 +000011552 statvfs_result_desc.name = MODNAME ".statvfs_result";
11553 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011554#ifdef NEED_TICKS_PER_SECOND
11555# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011556 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011557# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011558 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011559# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011560 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011561# endif
11562#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011563
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050011564#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011565 sched_param_desc.name = MODNAME ".sched_param";
11566 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
11567 SchedParamType.tp_new = sched_param_new;
11568#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011569
11570 /* initialize TerminalSize_info */
11571 PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc);
11572 Py_INCREF(&TerminalSizeType);
Victor Stinner8c62be82010-05-06 00:08:46 +000011573 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011574#if defined(HAVE_WAITID) && !defined(__APPLE__)
11575 Py_INCREF((PyObject*) &WaitidResultType);
11576 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
11577#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011578 Py_INCREF((PyObject*) &StatResultType);
11579 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11580 Py_INCREF((PyObject*) &StatVFSResultType);
11581 PyModule_AddObject(m, "statvfs_result",
11582 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011583
11584#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011585 Py_INCREF(&SchedParamType);
11586 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011587#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011588 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011589
11590#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000011591 /*
11592 * Step 2 of weak-linking support on Mac OS X.
11593 *
11594 * The code below removes functions that are not available on the
11595 * currently active platform.
11596 *
11597 * This block allow one to use a python binary that was build on
11598 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
11599 * OSX 10.4.
11600 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011601#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011602 if (fstatvfs == NULL) {
11603 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
11604 return NULL;
11605 }
11606 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011607#endif /* HAVE_FSTATVFS */
11608
11609#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011610 if (statvfs == NULL) {
11611 if (PyObject_DelAttrString(m, "statvfs") == -1) {
11612 return NULL;
11613 }
11614 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011615#endif /* HAVE_STATVFS */
11616
11617# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011618 if (lchown == NULL) {
11619 if (PyObject_DelAttrString(m, "lchown") == -1) {
11620 return NULL;
11621 }
11622 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011623#endif /* HAVE_LCHOWN */
11624
11625
11626#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011627
11628 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
11629
Victor Stinner8c62be82010-05-06 00:08:46 +000011630 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011631
Guido van Rossumb6775db1994-08-01 11:34:53 +000011632}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011633
11634#ifdef __cplusplus
11635}
11636#endif