blob: 094108a29f84aaa79d714dc23c88165af6ddd06e [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 Peterson2dbda072012-03-16 10:12:55 -0500110#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500111#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"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001553 {"st_atime_ns", "time of last access in nanoseconds"},
1554 {"st_mtime_ns", "time of last modification in nanoseconds"},
1555 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001556#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001557 {"st_blksize", "blocksize for filesystem I/O"},
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_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001560 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001561#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001562#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001563 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001564#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001565#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001566 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001567#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001568#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001569 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001570#endif
1571#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001572 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001573#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001574 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001575};
1576
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001577#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001578#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001579#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001580#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001581#endif
1582
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001583#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001584#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1585#else
1586#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1587#endif
1588
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001589#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001590#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1591#else
1592#define ST_RDEV_IDX ST_BLOCKS_IDX
1593#endif
1594
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001595#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1596#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1597#else
1598#define ST_FLAGS_IDX ST_RDEV_IDX
1599#endif
1600
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001601#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001602#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001603#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001604#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001605#endif
1606
1607#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1608#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1609#else
1610#define ST_BIRTHTIME_IDX ST_GEN_IDX
1611#endif
1612
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001613static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001614 "stat_result", /* name */
1615 stat_result__doc__, /* doc */
1616 stat_result_fields,
1617 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001618};
1619
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001620PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001621"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1622This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001623 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001624or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001625\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001626See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001627
1628static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001629 {"f_bsize", },
1630 {"f_frsize", },
1631 {"f_blocks", },
1632 {"f_bfree", },
1633 {"f_bavail", },
1634 {"f_files", },
1635 {"f_ffree", },
1636 {"f_favail", },
1637 {"f_flag", },
1638 {"f_namemax",},
1639 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001640};
1641
1642static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001643 "statvfs_result", /* name */
1644 statvfs_result__doc__, /* doc */
1645 statvfs_result_fields,
1646 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001647};
1648
Ross Lagerwall7807c352011-03-17 20:20:30 +02001649#if defined(HAVE_WAITID) && !defined(__APPLE__)
1650PyDoc_STRVAR(waitid_result__doc__,
1651"waitid_result: Result from waitid.\n\n\
1652This object may be accessed either as a tuple of\n\
1653 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1654or via the attributes si_pid, si_uid, and so on.\n\
1655\n\
1656See os.waitid for more information.");
1657
1658static PyStructSequence_Field waitid_result_fields[] = {
1659 {"si_pid", },
1660 {"si_uid", },
1661 {"si_signo", },
1662 {"si_status", },
1663 {"si_code", },
1664 {0}
1665};
1666
1667static PyStructSequence_Desc waitid_result_desc = {
1668 "waitid_result", /* name */
1669 waitid_result__doc__, /* doc */
1670 waitid_result_fields,
1671 5
1672};
1673static PyTypeObject WaitidResultType;
1674#endif
1675
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001676static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001677static PyTypeObject StatResultType;
1678static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001679#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001680static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001681#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001682static newfunc structseq_new;
1683
1684static PyObject *
1685statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1686{
Victor Stinner8c62be82010-05-06 00:08:46 +00001687 PyStructSequence *result;
1688 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001689
Victor Stinner8c62be82010-05-06 00:08:46 +00001690 result = (PyStructSequence*)structseq_new(type, args, kwds);
1691 if (!result)
1692 return NULL;
1693 /* If we have been initialized from a tuple,
1694 st_?time might be set to None. Initialize it
1695 from the int slots. */
1696 for (i = 7; i <= 9; i++) {
1697 if (result->ob_item[i+3] == Py_None) {
1698 Py_DECREF(Py_None);
1699 Py_INCREF(result->ob_item[i]);
1700 result->ob_item[i+3] = result->ob_item[i];
1701 }
1702 }
1703 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001704}
1705
1706
1707
1708/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001709static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001710
1711PyDoc_STRVAR(stat_float_times__doc__,
1712"stat_float_times([newval]) -> oldval\n\n\
1713Determine whether os.[lf]stat represents time stamps as float objects.\n\
1714If newval is True, future calls to stat() return floats, if it is False,\n\
1715future calls return ints. \n\
1716If newval is omitted, return the current setting.\n");
1717
1718static PyObject*
1719stat_float_times(PyObject* self, PyObject *args)
1720{
Victor Stinner8c62be82010-05-06 00:08:46 +00001721 int newval = -1;
1722 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1723 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001724 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1725 "stat_float_times() is deprecated",
1726 1))
1727 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001728 if (newval == -1)
1729 /* Return old value */
1730 return PyBool_FromLong(_stat_float_times);
1731 _stat_float_times = newval;
1732 Py_INCREF(Py_None);
1733 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001734}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001735
Larry Hastings6fe20b32012-04-19 15:07:49 -07001736static PyObject *billion = NULL;
1737
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001738static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001739fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001740{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001741 PyObject *s = _PyLong_FromTime_t(sec);
1742 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1743 PyObject *s_in_ns = NULL;
1744 PyObject *ns_total = NULL;
1745 PyObject *float_s = NULL;
1746
1747 if (!(s && ns_fractional))
1748 goto exit;
1749
1750 s_in_ns = PyNumber_Multiply(s, billion);
1751 if (!s_in_ns)
1752 goto exit;
1753
1754 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1755 if (!ns_total)
1756 goto exit;
1757
Victor Stinner4195b5c2012-02-08 23:03:19 +01001758 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001759 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1760 if (!float_s)
1761 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001762 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001763 else {
1764 float_s = s;
1765 Py_INCREF(float_s);
1766 }
1767
1768 PyStructSequence_SET_ITEM(v, index, s);
1769 PyStructSequence_SET_ITEM(v, index+3, float_s);
1770 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1771 s = NULL;
1772 float_s = NULL;
1773 ns_total = NULL;
1774exit:
1775 Py_XDECREF(s);
1776 Py_XDECREF(ns_fractional);
1777 Py_XDECREF(s_in_ns);
1778 Py_XDECREF(ns_total);
1779 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001780}
1781
Tim Peters5aa91602002-01-30 05:46:57 +00001782/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001783 (used by posix_stat() and posix_fstat()) */
1784static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001785_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001786{
Victor Stinner8c62be82010-05-06 00:08:46 +00001787 unsigned long ansec, mnsec, cnsec;
1788 PyObject *v = PyStructSequence_New(&StatResultType);
1789 if (v == NULL)
1790 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001791
Victor Stinner8c62be82010-05-06 00:08:46 +00001792 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001793#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001794 PyStructSequence_SET_ITEM(v, 1,
1795 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001796#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001797 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001798#endif
1799#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001800 PyStructSequence_SET_ITEM(v, 2,
1801 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001802#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001803 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001804#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001805 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1806 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1807 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001808#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001809 PyStructSequence_SET_ITEM(v, 6,
1810 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001811#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001812 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001813#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001814
Martin v. Löwis14694662006-02-03 12:54:16 +00001815#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001816 ansec = st->st_atim.tv_nsec;
1817 mnsec = st->st_mtim.tv_nsec;
1818 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001819#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001820 ansec = st->st_atimespec.tv_nsec;
1821 mnsec = st->st_mtimespec.tv_nsec;
1822 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001823#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001824 ansec = st->st_atime_nsec;
1825 mnsec = st->st_mtime_nsec;
1826 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001827#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001828 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001829#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01001830 fill_time(v, 7, st->st_atime, ansec);
1831 fill_time(v, 8, st->st_mtime, mnsec);
1832 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001833
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001834#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001835 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1836 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001837#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001838#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001839 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1840 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001841#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001842#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001843 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1844 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001845#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001846#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001847 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1848 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001849#endif
1850#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001851 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01001852 PyObject *val;
1853 unsigned long bsec,bnsec;
1854 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001855#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01001856 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001857#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01001858 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001859#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01001860 if (_stat_float_times) {
1861 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1862 } else {
1863 val = PyLong_FromLong((long)bsec);
1864 }
1865 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1866 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00001867 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001868#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001869#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001870 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1871 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001872#endif
Fred Drake699f3522000-06-29 21:12:41 +00001873
Victor Stinner8c62be82010-05-06 00:08:46 +00001874 if (PyErr_Occurred()) {
1875 Py_DECREF(v);
1876 return NULL;
1877 }
Fred Drake699f3522000-06-29 21:12:41 +00001878
Victor Stinner8c62be82010-05-06 00:08:46 +00001879 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001880}
1881
Barry Warsaw53699e91996-12-10 23:23:01 +00001882static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01001883posix_do_stat(PyObject *self, PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +00001884 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001885#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00001886 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001887#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001888 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001889#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001890 char *wformat,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001891 int (*wstatfunc)(const wchar_t *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001892{
Victor Stinner8c62be82010-05-06 00:08:46 +00001893 STRUCT_STAT st;
1894 PyObject *opath;
1895 char *path;
1896 int res;
1897 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001898
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001899#ifdef MS_WINDOWS
Victor Stinnereb5657a2011-09-30 01:44:27 +02001900 PyObject *po;
Victor Stinner4195b5c2012-02-08 23:03:19 +01001901 if (PyArg_ParseTuple(args, wformat, &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02001902 wchar_t *wpath = PyUnicode_AsUnicode(po);
1903 if (wpath == NULL)
1904 return NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00001905
Victor Stinner8c62be82010-05-06 00:08:46 +00001906 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00001907 res = wstatfunc(wpath, &st);
1908 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001909
Victor Stinner8c62be82010-05-06 00:08:46 +00001910 if (res != 0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001911 return win32_error_object("stat", po);
Victor Stinner4195b5c2012-02-08 23:03:19 +01001912 return _pystat_fromstructstat(&st);
Victor Stinner8c62be82010-05-06 00:08:46 +00001913 }
1914 /* Drop the argument parsing error as narrow strings
1915 are also valid. */
1916 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001917#endif
1918
Victor Stinner4195b5c2012-02-08 23:03:19 +01001919 if (!PyArg_ParseTuple(args, format,
1920 PyUnicode_FSConverter, &opath))
Victor Stinner8c62be82010-05-06 00:08:46 +00001921 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001922#ifdef MS_WINDOWS
1923 if (win32_warn_bytes_api()) {
1924 Py_DECREF(opath);
1925 return NULL;
1926 }
1927#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001928 path = PyBytes_AsString(opath);
1929 Py_BEGIN_ALLOW_THREADS
1930 res = (*statfunc)(path, &st);
1931 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001932
Victor Stinner8c62be82010-05-06 00:08:46 +00001933 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001934#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001935 result = win32_error("stat", path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001936#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001937 result = posix_error_with_filename(path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001938#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001939 }
1940 else
Victor Stinner4195b5c2012-02-08 23:03:19 +01001941 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001942
Victor Stinner8c62be82010-05-06 00:08:46 +00001943 Py_DECREF(opath);
1944 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001945}
1946
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001947/* POSIX methods */
1948
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001949PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001950"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001951Use the real uid/gid to test for access to a path. Note that most\n\
1952operations will use the effective uid/gid, therefore this routine can\n\
1953be used in a suid/sgid environment to test if the invoking user has the\n\
1954specified access to the path. The mode argument can be F_OK to test\n\
1955existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001956
1957static PyObject *
Benjamin Petersoneaa5eee2012-05-05 21:22:14 -04001958posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001959{
Benjamin Petersoneaa5eee2012-05-05 21:22:14 -04001960 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001961 int mode;
1962
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001963#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001964 DWORD attr;
Benjamin Petersoneaa5eee2012-05-05 21:22:14 -04001965 PyObject *po;
1966 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1967 wchar_t* wpath = PyUnicode_AsUnicode(po);
1968 if (wpath == NULL)
1969 return NULL;
1970 Py_BEGIN_ALLOW_THREADS
1971 attr = GetFileAttributesW(wpath);
1972 Py_END_ALLOW_THREADS
1973 goto finish;
1974 }
1975 /* Drop the argument parsing error as narrow strings
1976 are also valid. */
1977 PyErr_Clear();
1978 if (!PyArg_ParseTuple(args, "yi:access", &path, &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00001979 return NULL;
Benjamin Petersoneaa5eee2012-05-05 21:22:14 -04001980 if (win32_warn_bytes_api())
1981 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001982 Py_BEGIN_ALLOW_THREADS
Benjamin Petersoneaa5eee2012-05-05 21:22:14 -04001983 attr = GetFileAttributesA(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001984 Py_END_ALLOW_THREADS
Benjamin Petersoneaa5eee2012-05-05 21:22:14 -04001985finish:
Victor Stinner8c62be82010-05-06 00:08:46 +00001986 if (attr == 0xFFFFFFFF)
1987 /* File does not exist, or cannot read attributes */
1988 return PyBool_FromLong(0);
1989 /* Access is possible if either write access wasn't requested, or
1990 the file isn't read-only, or if it's a directory, as there are
1991 no read-only directories on Windows. */
1992 return PyBool_FromLong(!(mode & 2)
1993 || !(attr & FILE_ATTRIBUTE_READONLY)
1994 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001995#else
Benjamin Petersoneaa5eee2012-05-05 21:22:14 -04001996 PyObject *opath;
1997 int res;
1998 if (!PyArg_ParseTuple(args, "O&i:access",
1999 PyUnicode_FSConverter, &opath, &mode))
2000 return NULL;
2001 path = PyBytes_AsString(opath);
2002 Py_BEGIN_ALLOW_THREADS
2003 res = access(path, mode);
2004 Py_END_ALLOW_THREADS
2005 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00002006 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002007#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002008}
2009
Guido van Rossumd371ff11999-01-25 16:12:23 +00002010#ifndef F_OK
2011#define F_OK 0
2012#endif
2013#ifndef R_OK
2014#define R_OK 4
2015#endif
2016#ifndef W_OK
2017#define W_OK 2
2018#endif
2019#ifndef X_OK
2020#define X_OK 1
2021#endif
2022
2023#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002024PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002025"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002026Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00002027
2028static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002029posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002030{
Victor Stinner8c62be82010-05-06 00:08:46 +00002031 int id;
2032 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002033
Victor Stinner8c62be82010-05-06 00:08:46 +00002034 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
2035 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002036
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002037#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002038 /* file descriptor 0 only, the default input device (stdin) */
2039 if (id == 0) {
2040 ret = ttyname();
2041 }
2042 else {
2043 ret = NULL;
2044 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002045#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002046 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002047#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002048 if (ret == NULL)
2049 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002050 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002051}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002052#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002053
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002054#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002055PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002056"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002057Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002058
2059static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002060posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002061{
Victor Stinner8c62be82010-05-06 00:08:46 +00002062 char *ret;
2063 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002064
Greg Wardb48bc172000-03-01 21:51:56 +00002065#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002066 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002067#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002068 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002069#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002070 if (ret == NULL)
2071 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002072 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002073}
2074#endif
2075
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002076PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002077"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002078Change the current working directory to the specified path.");
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_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002082{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002083#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002084 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002085#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002086 return posix_1str(args, "O&:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00002087#elif defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002088 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002089#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002090 return posix_1str(args, "O&:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002091#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002092}
2093
Fred Drake4d1e64b2002-04-15 19:40:07 +00002094#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002095PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002096"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00002097Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002098opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002099
2100static PyObject *
2101posix_fchdir(PyObject *self, PyObject *fdobj)
2102{
Victor Stinner8c62be82010-05-06 00:08:46 +00002103 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002104}
2105#endif /* HAVE_FCHDIR */
2106
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002107
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002108PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002109"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002110Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002111
Barry Warsaw53699e91996-12-10 23:23:01 +00002112static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002113posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002114{
Victor Stinner8c62be82010-05-06 00:08:46 +00002115 PyObject *opath = NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002116 const char *path = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002117 int i;
2118 int res;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002119#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002120 DWORD attr;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002121 PyObject *po;
Victor Stinner8c62be82010-05-06 00:08:46 +00002122 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02002123 wchar_t *wpath = PyUnicode_AsUnicode(po);
2124 if (wpath == NULL)
2125 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002126 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02002127 attr = GetFileAttributesW(wpath);
Victor Stinner8c62be82010-05-06 00:08:46 +00002128 if (attr != 0xFFFFFFFF) {
2129 if (i & _S_IWRITE)
2130 attr &= ~FILE_ATTRIBUTE_READONLY;
2131 else
2132 attr |= FILE_ATTRIBUTE_READONLY;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002133 res = SetFileAttributesW(wpath, attr);
Victor Stinner8c62be82010-05-06 00:08:46 +00002134 }
2135 else
2136 res = 0;
2137 Py_END_ALLOW_THREADS
2138 if (!res)
Victor Stinnereb5657a2011-09-30 01:44:27 +02002139 return win32_error_object("chmod", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00002140 Py_INCREF(Py_None);
2141 return Py_None;
2142 }
2143 /* Drop the argument parsing error as narrow strings
2144 are also valid. */
2145 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002146
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002147 if (!PyArg_ParseTuple(args, "yi:chmod", &path, &i))
Victor Stinner8c62be82010-05-06 00:08:46 +00002148 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002149 if (win32_warn_bytes_api())
2150 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002151 Py_BEGIN_ALLOW_THREADS
2152 attr = GetFileAttributesA(path);
2153 if (attr != 0xFFFFFFFF) {
2154 if (i & _S_IWRITE)
2155 attr &= ~FILE_ATTRIBUTE_READONLY;
2156 else
2157 attr |= FILE_ATTRIBUTE_READONLY;
2158 res = SetFileAttributesA(path, attr);
2159 }
2160 else
2161 res = 0;
2162 Py_END_ALLOW_THREADS
2163 if (!res) {
2164 win32_error("chmod", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00002165 return NULL;
2166 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002167 Py_INCREF(Py_None);
2168 return Py_None;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002169#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00002170 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
2171 &opath, &i))
2172 return NULL;
2173 path = PyBytes_AsString(opath);
2174 Py_BEGIN_ALLOW_THREADS
2175 res = chmod(path, i);
2176 Py_END_ALLOW_THREADS
2177 if (res < 0)
2178 return posix_error_with_allocated_filename(opath);
2179 Py_DECREF(opath);
2180 Py_INCREF(Py_None);
2181 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002182#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002183}
2184
Christian Heimes4e30a842007-11-30 22:12:06 +00002185#ifdef HAVE_FCHMOD
2186PyDoc_STRVAR(posix_fchmod__doc__,
2187"fchmod(fd, mode)\n\n\
2188Change the access permissions of the file given by file\n\
2189descriptor fd.");
2190
2191static PyObject *
2192posix_fchmod(PyObject *self, PyObject *args)
2193{
Victor Stinner8c62be82010-05-06 00:08:46 +00002194 int fd, mode, res;
2195 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2196 return NULL;
2197 Py_BEGIN_ALLOW_THREADS
2198 res = fchmod(fd, mode);
2199 Py_END_ALLOW_THREADS
2200 if (res < 0)
2201 return posix_error();
2202 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002203}
2204#endif /* HAVE_FCHMOD */
2205
2206#ifdef HAVE_LCHMOD
2207PyDoc_STRVAR(posix_lchmod__doc__,
2208"lchmod(path, mode)\n\n\
2209Change the access permissions of a file. If path is a symlink, this\n\
2210affects the link itself rather than the target.");
2211
2212static PyObject *
2213posix_lchmod(PyObject *self, PyObject *args)
2214{
Victor Stinner8c62be82010-05-06 00:08:46 +00002215 PyObject *opath;
2216 char *path;
2217 int i;
2218 int res;
2219 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
2220 &opath, &i))
2221 return NULL;
2222 path = PyBytes_AsString(opath);
2223 Py_BEGIN_ALLOW_THREADS
2224 res = lchmod(path, i);
2225 Py_END_ALLOW_THREADS
2226 if (res < 0)
2227 return posix_error_with_allocated_filename(opath);
2228 Py_DECREF(opath);
2229 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002230}
2231#endif /* HAVE_LCHMOD */
2232
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002233
Thomas Wouterscf297e42007-02-23 15:07:44 +00002234#ifdef HAVE_CHFLAGS
2235PyDoc_STRVAR(posix_chflags__doc__,
2236"chflags(path, flags)\n\n\
2237Set file flags.");
2238
2239static PyObject *
2240posix_chflags(PyObject *self, PyObject *args)
2241{
Victor Stinner8c62be82010-05-06 00:08:46 +00002242 PyObject *opath;
2243 char *path;
2244 unsigned long flags;
2245 int res;
2246 if (!PyArg_ParseTuple(args, "O&k:chflags",
2247 PyUnicode_FSConverter, &opath, &flags))
2248 return NULL;
2249 path = PyBytes_AsString(opath);
2250 Py_BEGIN_ALLOW_THREADS
2251 res = chflags(path, flags);
2252 Py_END_ALLOW_THREADS
2253 if (res < 0)
2254 return posix_error_with_allocated_filename(opath);
2255 Py_DECREF(opath);
2256 Py_INCREF(Py_None);
2257 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002258}
2259#endif /* HAVE_CHFLAGS */
2260
2261#ifdef HAVE_LCHFLAGS
2262PyDoc_STRVAR(posix_lchflags__doc__,
2263"lchflags(path, flags)\n\n\
2264Set file flags.\n\
2265This function will not follow symbolic links.");
2266
2267static PyObject *
2268posix_lchflags(PyObject *self, PyObject *args)
2269{
Victor Stinner8c62be82010-05-06 00:08:46 +00002270 PyObject *opath;
2271 char *path;
2272 unsigned long flags;
2273 int res;
2274 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2275 PyUnicode_FSConverter, &opath, &flags))
2276 return NULL;
2277 path = PyBytes_AsString(opath);
2278 Py_BEGIN_ALLOW_THREADS
2279 res = lchflags(path, flags);
2280 Py_END_ALLOW_THREADS
2281 if (res < 0)
2282 return posix_error_with_allocated_filename(opath);
2283 Py_DECREF(opath);
2284 Py_INCREF(Py_None);
2285 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002286}
2287#endif /* HAVE_LCHFLAGS */
2288
Martin v. Löwis244edc82001-10-04 22:44:26 +00002289#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002290PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002291"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002292Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002293
2294static PyObject *
2295posix_chroot(PyObject *self, PyObject *args)
2296{
Victor Stinner8c62be82010-05-06 00:08:46 +00002297 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002298}
2299#endif
2300
Guido van Rossum21142a01999-01-08 21:05:37 +00002301#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002302PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002303"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002304force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002305
2306static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002307posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002308{
Stefan Krah0e803b32010-11-26 16:16:47 +00002309 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002310}
2311#endif /* HAVE_FSYNC */
2312
Ross Lagerwall7807c352011-03-17 20:20:30 +02002313#ifdef HAVE_SYNC
2314PyDoc_STRVAR(posix_sync__doc__,
2315"sync()\n\n\
2316Force write of everything to disk.");
2317
2318static PyObject *
2319posix_sync(PyObject *self, PyObject *noargs)
2320{
2321 Py_BEGIN_ALLOW_THREADS
2322 sync();
2323 Py_END_ALLOW_THREADS
2324 Py_RETURN_NONE;
2325}
2326#endif
2327
Guido van Rossum21142a01999-01-08 21:05:37 +00002328#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002329
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002330#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002331extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2332#endif
2333
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002334PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002335"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002336force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002337 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002338
2339static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002340posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002341{
Stefan Krah0e803b32010-11-26 16:16:47 +00002342 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002343}
2344#endif /* HAVE_FDATASYNC */
2345
2346
Fredrik Lundh10723342000-07-10 16:38:09 +00002347#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002348PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002349"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002350Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002351
Barry Warsaw53699e91996-12-10 23:23:01 +00002352static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002353posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002354{
Victor Stinner8c62be82010-05-06 00:08:46 +00002355 PyObject *opath;
2356 char *path;
2357 long uid, gid;
2358 int res;
2359 if (!PyArg_ParseTuple(args, "O&ll:chown",
2360 PyUnicode_FSConverter, &opath,
2361 &uid, &gid))
2362 return NULL;
2363 path = PyBytes_AsString(opath);
2364 Py_BEGIN_ALLOW_THREADS
2365 res = chown(path, (uid_t) uid, (gid_t) gid);
2366 Py_END_ALLOW_THREADS
2367 if (res < 0)
2368 return posix_error_with_allocated_filename(opath);
2369 Py_DECREF(opath);
2370 Py_INCREF(Py_None);
2371 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002372}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002373#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002374
Christian Heimes4e30a842007-11-30 22:12:06 +00002375#ifdef HAVE_FCHOWN
2376PyDoc_STRVAR(posix_fchown__doc__,
2377"fchown(fd, uid, gid)\n\n\
2378Change the owner and group id of the file given by file descriptor\n\
2379fd to the numeric uid and gid.");
2380
2381static PyObject *
2382posix_fchown(PyObject *self, PyObject *args)
2383{
Victor Stinner8c62be82010-05-06 00:08:46 +00002384 int fd;
2385 long uid, gid;
2386 int res;
Victor Stinner26de69d2011-06-17 15:15:38 +02002387 if (!PyArg_ParseTuple(args, "ill:fchown", &fd, &uid, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00002388 return NULL;
2389 Py_BEGIN_ALLOW_THREADS
2390 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2391 Py_END_ALLOW_THREADS
2392 if (res < 0)
2393 return posix_error();
2394 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002395}
2396#endif /* HAVE_FCHOWN */
2397
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002398#ifdef HAVE_LCHOWN
2399PyDoc_STRVAR(posix_lchown__doc__,
2400"lchown(path, uid, gid)\n\n\
2401Change the owner and group id of path to the numeric uid and gid.\n\
2402This function will not follow symbolic links.");
2403
2404static PyObject *
2405posix_lchown(PyObject *self, PyObject *args)
2406{
Victor Stinner8c62be82010-05-06 00:08:46 +00002407 PyObject *opath;
2408 char *path;
2409 long uid, gid;
2410 int res;
2411 if (!PyArg_ParseTuple(args, "O&ll:lchown",
2412 PyUnicode_FSConverter, &opath,
2413 &uid, &gid))
2414 return NULL;
2415 path = PyBytes_AsString(opath);
2416 Py_BEGIN_ALLOW_THREADS
2417 res = lchown(path, (uid_t) uid, (gid_t) gid);
2418 Py_END_ALLOW_THREADS
2419 if (res < 0)
2420 return posix_error_with_allocated_filename(opath);
2421 Py_DECREF(opath);
2422 Py_INCREF(Py_None);
2423 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002424}
2425#endif /* HAVE_LCHOWN */
2426
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002427
Guido van Rossum36bc6801995-06-14 22:54:23 +00002428#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002429static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002430posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002431{
Victor Stinner8c62be82010-05-06 00:08:46 +00002432 char buf[1026];
2433 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002434
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002435#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002436 if (!use_bytes) {
2437 wchar_t wbuf[1026];
2438 wchar_t *wbuf2 = wbuf;
2439 PyObject *resobj;
2440 DWORD len;
2441 Py_BEGIN_ALLOW_THREADS
2442 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2443 /* If the buffer is large enough, len does not include the
2444 terminating \0. If the buffer is too small, len includes
2445 the space needed for the terminator. */
2446 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2447 wbuf2 = malloc(len * sizeof(wchar_t));
2448 if (wbuf2)
2449 len = GetCurrentDirectoryW(len, wbuf2);
2450 }
2451 Py_END_ALLOW_THREADS
2452 if (!wbuf2) {
2453 PyErr_NoMemory();
2454 return NULL;
2455 }
2456 if (!len) {
2457 if (wbuf2 != wbuf) free(wbuf2);
2458 return win32_error("getcwdu", NULL);
2459 }
2460 resobj = PyUnicode_FromWideChar(wbuf2, len);
2461 if (wbuf2 != wbuf) free(wbuf2);
2462 return resobj;
2463 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01002464
2465 if (win32_warn_bytes_api())
2466 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002467#endif
2468
Victor Stinner8c62be82010-05-06 00:08:46 +00002469 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002470#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002471 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002472#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002473 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002474#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002475 Py_END_ALLOW_THREADS
2476 if (res == NULL)
2477 return posix_error();
2478 if (use_bytes)
2479 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00002480 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002481}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002482
2483PyDoc_STRVAR(posix_getcwd__doc__,
2484"getcwd() -> path\n\n\
2485Return a unicode string representing the current working directory.");
2486
2487static PyObject *
2488posix_getcwd_unicode(PyObject *self)
2489{
2490 return posix_getcwd(0);
2491}
2492
2493PyDoc_STRVAR(posix_getcwdb__doc__,
2494"getcwdb() -> path\n\n\
2495Return a bytes string representing the current working directory.");
2496
2497static PyObject *
2498posix_getcwd_bytes(PyObject *self)
2499{
2500 return posix_getcwd(1);
2501}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002502#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002503
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002504
Guido van Rossumb6775db1994-08-01 11:34:53 +00002505#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002506PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002507"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002508Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002509
Barry Warsaw53699e91996-12-10 23:23:01 +00002510static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002511posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002512{
Victor Stinner8c62be82010-05-06 00:08:46 +00002513 return posix_2str(args, "O&O&:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002514}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002515#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002516
Brian Curtin1b9df392010-11-24 20:24:31 +00002517#ifdef MS_WINDOWS
2518PyDoc_STRVAR(win32_link__doc__,
2519"link(src, dst)\n\n\
2520Create a hard link to a file.");
2521
2522static PyObject *
2523win32_link(PyObject *self, PyObject *args)
2524{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002525 PyObject *src, *dst;
2526 BOOL ok;
Brian Curtin1b9df392010-11-24 20:24:31 +00002527
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002528 if (PyArg_ParseTuple(args, "UU:link", &src, &dst))
Victor Stinnereb5657a2011-09-30 01:44:27 +02002529 {
2530 wchar_t *wsrc, *wdst;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002531
2532 wsrc = PyUnicode_AsUnicode(src);
Victor Stinnereb5657a2011-09-30 01:44:27 +02002533 if (wsrc == NULL)
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002534 goto error;
2535 wdst = PyUnicode_AsUnicode(dst);
Victor Stinnereb5657a2011-09-30 01:44:27 +02002536 if (wdst == NULL)
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002537 goto error;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002538
Brian Curtinfc889c42010-11-28 23:59:46 +00002539 Py_BEGIN_ALLOW_THREADS
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002540 ok = CreateHardLinkW(wdst, wsrc, NULL);
Brian Curtinfc889c42010-11-28 23:59:46 +00002541 Py_END_ALLOW_THREADS
2542
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002543 if (!ok)
Brian Curtinfc889c42010-11-28 23:59:46 +00002544 return win32_error("link", NULL);
Brian Curtinfc889c42010-11-28 23:59:46 +00002545 Py_RETURN_NONE;
2546 }
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002547 else {
2548 PyErr_Clear();
2549 if (!PyArg_ParseTuple(args, "O&O&:link",
2550 PyUnicode_FSConverter, &src,
2551 PyUnicode_FSConverter, &dst))
2552 return NULL;
Brian Curtinfc889c42010-11-28 23:59:46 +00002553
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002554 if (win32_warn_bytes_api())
2555 goto error;
Brian Curtinfc889c42010-11-28 23:59:46 +00002556
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002557 Py_BEGIN_ALLOW_THREADS
2558 ok = CreateHardLinkA(PyBytes_AS_STRING(dst),
2559 PyBytes_AS_STRING(src),
2560 NULL);
2561 Py_END_ALLOW_THREADS
2562
2563 Py_XDECREF(src);
2564 Py_XDECREF(dst);
2565
2566 if (!ok)
2567 return win32_error("link", NULL);
2568 Py_RETURN_NONE;
2569
2570 error:
2571 Py_XDECREF(src);
2572 Py_XDECREF(dst);
Brian Curtin1b9df392010-11-24 20:24:31 +00002573 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002574 }
Brian Curtin1b9df392010-11-24 20:24:31 +00002575}
2576#endif /* MS_WINDOWS */
2577
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002578
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002579PyDoc_STRVAR(posix_listdir__doc__,
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002580"listdir([path]) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002581Return a list containing the names of the entries in the directory.\n\
2582\n\
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002583 path: path of directory to list (default: '.')\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002584\n\
2585The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002586entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002587
Barry Warsaw53699e91996-12-10 23:23:01 +00002588static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002589posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002590{
Victor Stinner8c62be82010-05-06 00:08:46 +00002591 /* XXX Should redo this putting the (now four) versions of opendir
2592 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002593#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002594
Victor Stinner8c62be82010-05-06 00:08:46 +00002595 PyObject *d, *v;
2596 HANDLE hFindFile;
2597 BOOL result;
2598 WIN32_FIND_DATA FileData;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002599 const char *path;
2600 Py_ssize_t pathlen;
Victor Stinner8c62be82010-05-06 00:08:46 +00002601 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2602 char *bufptr = namebuf;
2603 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002604
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002605 PyObject *po = NULL;
2606 if (PyArg_ParseTuple(args, "|U:listdir", &po)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002607 WIN32_FIND_DATAW wFileData;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002608 wchar_t *wnamebuf, *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002609
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002610 if (po == NULL) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002611 po_wchars = L".";
2612 len = 1;
2613 } else {
Victor Stinnerbeac78b2011-10-11 21:55:01 +02002614 po_wchars = PyUnicode_AsUnicodeAndSize(po, &len);
Victor Stinnereb5657a2011-09-30 01:44:27 +02002615 if (po_wchars == NULL)
2616 return NULL;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002617 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002618 /* Overallocate for \\*.*\0 */
Victor Stinner8c62be82010-05-06 00:08:46 +00002619 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2620 if (!wnamebuf) {
2621 PyErr_NoMemory();
2622 return NULL;
2623 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002624 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00002625 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02002626 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00002627 if (wch != L'/' && wch != L'\\' && wch != L':')
2628 wnamebuf[len++] = L'\\';
2629 wcscpy(wnamebuf + len, L"*.*");
2630 }
2631 if ((d = PyList_New(0)) == NULL) {
2632 free(wnamebuf);
2633 return NULL;
2634 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00002635 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002636 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002637 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002638 if (hFindFile == INVALID_HANDLE_VALUE) {
2639 int error = GetLastError();
2640 if (error == ERROR_FILE_NOT_FOUND) {
2641 free(wnamebuf);
2642 return d;
2643 }
2644 Py_DECREF(d);
2645 win32_error_unicode("FindFirstFileW", wnamebuf);
2646 free(wnamebuf);
2647 return NULL;
2648 }
2649 do {
2650 /* Skip over . and .. */
2651 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2652 wcscmp(wFileData.cFileName, L"..") != 0) {
Victor Stinner9d3b93b2011-11-22 02:27:30 +01002653 v = PyUnicode_FromWideChar(wFileData.cFileName, wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00002654 if (v == NULL) {
2655 Py_DECREF(d);
2656 d = NULL;
2657 break;
2658 }
2659 if (PyList_Append(d, v) != 0) {
2660 Py_DECREF(v);
2661 Py_DECREF(d);
2662 d = NULL;
2663 break;
2664 }
2665 Py_DECREF(v);
2666 }
2667 Py_BEGIN_ALLOW_THREADS
2668 result = FindNextFileW(hFindFile, &wFileData);
2669 Py_END_ALLOW_THREADS
2670 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2671 it got to the end of the directory. */
2672 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2673 Py_DECREF(d);
2674 win32_error_unicode("FindNextFileW", wnamebuf);
2675 FindClose(hFindFile);
2676 free(wnamebuf);
2677 return NULL;
2678 }
2679 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002680
Victor Stinner8c62be82010-05-06 00:08:46 +00002681 if (FindClose(hFindFile) == FALSE) {
2682 Py_DECREF(d);
2683 win32_error_unicode("FindClose", wnamebuf);
2684 free(wnamebuf);
2685 return NULL;
2686 }
2687 free(wnamebuf);
2688 return d;
2689 }
2690 /* Drop the argument parsing error as narrow strings
2691 are also valid. */
2692 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002693
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002694 if (!PyArg_ParseTuple(args, "y#:listdir", &path, &pathlen))
Victor Stinner8c62be82010-05-06 00:08:46 +00002695 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002696 if (win32_warn_bytes_api())
2697 return NULL;
2698 if (pathlen+1 > MAX_PATH) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002699 PyErr_SetString(PyExc_ValueError, "path too long");
Victor Stinner8c62be82010-05-06 00:08:46 +00002700 return NULL;
2701 }
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002702 strcpy(namebuf, path);
2703 len = pathlen;
Victor Stinner8c62be82010-05-06 00:08:46 +00002704 if (len > 0) {
2705 char ch = namebuf[len-1];
2706 if (ch != SEP && ch != ALTSEP && ch != ':')
2707 namebuf[len++] = '/';
2708 strcpy(namebuf + len, "*.*");
2709 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002710
Victor Stinner8c62be82010-05-06 00:08:46 +00002711 if ((d = PyList_New(0)) == NULL)
2712 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002713
Antoine Pitroub73caab2010-08-09 23:39:31 +00002714 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002715 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002716 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002717 if (hFindFile == INVALID_HANDLE_VALUE) {
2718 int error = GetLastError();
2719 if (error == ERROR_FILE_NOT_FOUND)
2720 return d;
2721 Py_DECREF(d);
2722 return win32_error("FindFirstFile", namebuf);
2723 }
2724 do {
2725 /* Skip over . and .. */
2726 if (strcmp(FileData.cFileName, ".") != 0 &&
2727 strcmp(FileData.cFileName, "..") != 0) {
2728 v = PyBytes_FromString(FileData.cFileName);
2729 if (v == NULL) {
2730 Py_DECREF(d);
2731 d = NULL;
2732 break;
2733 }
2734 if (PyList_Append(d, v) != 0) {
2735 Py_DECREF(v);
2736 Py_DECREF(d);
2737 d = NULL;
2738 break;
2739 }
2740 Py_DECREF(v);
2741 }
2742 Py_BEGIN_ALLOW_THREADS
2743 result = FindNextFile(hFindFile, &FileData);
2744 Py_END_ALLOW_THREADS
2745 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2746 it got to the end of the directory. */
2747 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2748 Py_DECREF(d);
2749 win32_error("FindNextFile", namebuf);
2750 FindClose(hFindFile);
2751 return NULL;
2752 }
2753 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002754
Victor Stinner8c62be82010-05-06 00:08:46 +00002755 if (FindClose(hFindFile) == FALSE) {
2756 Py_DECREF(d);
2757 return win32_error("FindClose", namebuf);
2758 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002759
Victor Stinner8c62be82010-05-06 00:08:46 +00002760 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002761
Tim Peters0bb44a42000-09-15 07:44:49 +00002762#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002763
2764#ifndef MAX_PATH
2765#define MAX_PATH CCHMAXPATH
2766#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002767 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002768 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002769 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002770 PyObject *d, *v;
2771 char namebuf[MAX_PATH+5];
2772 HDIR hdir = 1;
2773 ULONG srchcnt = 1;
2774 FILEFINDBUF3 ep;
2775 APIRET rc;
2776
Victor Stinner8c62be82010-05-06 00:08:46 +00002777 if (!PyArg_ParseTuple(args, "O&:listdir",
Martin v. Löwis011e8422009-05-05 04:43:17 +00002778 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002779 return NULL;
Victor Stinnerdcb24032010-04-22 12:08:36 +00002780 name = PyBytes_AsString(oname);
2781 len = PyBytes_GET_SIZE(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002782 if (len >= MAX_PATH) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002783 Py_DECREF(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002784 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002785 return NULL;
2786 }
2787 strcpy(namebuf, name);
2788 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002789 if (*pt == ALTSEP)
2790 *pt = SEP;
2791 if (namebuf[len-1] != SEP)
2792 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002793 strcpy(namebuf + len, "*.*");
2794
Neal Norwitz6c913782007-10-14 03:23:09 +00002795 if ((d = PyList_New(0)) == NULL) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002796 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002797 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002798 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002799
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002800 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2801 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002802 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002803 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2804 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2805 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002806
2807 if (rc != NO_ERROR) {
2808 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002809 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002810 }
2811
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002812 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002813 do {
2814 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002815 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002816 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002817
2818 strcpy(namebuf, ep.achName);
2819
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002820 /* Leave Case of Name Alone -- In Native Form */
2821 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002822
Christian Heimes72b710a2008-05-26 13:28:38 +00002823 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002824 if (v == NULL) {
2825 Py_DECREF(d);
2826 d = NULL;
2827 break;
2828 }
2829 if (PyList_Append(d, v) != 0) {
2830 Py_DECREF(v);
2831 Py_DECREF(d);
2832 d = NULL;
2833 break;
2834 }
2835 Py_DECREF(v);
2836 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2837 }
2838
Victor Stinnerdcb24032010-04-22 12:08:36 +00002839 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002840 return d;
2841#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002842 PyObject *oname;
2843 char *name;
2844 PyObject *d, *v;
2845 DIR *dirp;
2846 struct dirent *ep;
2847 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002848
Victor Stinner8c62be82010-05-06 00:08:46 +00002849 errno = 0;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002850 /* v is never read, so it does not need to be initialized yet. */
2851 if (!PyArg_ParseTuple(args, "|U:listdir", &v)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002852 arg_is_unicode = 0;
2853 PyErr_Clear();
2854 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002855 oname = NULL;
2856 if (!PyArg_ParseTuple(args, "|O&:listdir", PyUnicode_FSConverter, &oname))
Victor Stinner8c62be82010-05-06 00:08:46 +00002857 return NULL;
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002858 if (oname == NULL) { /* Default arg: "." */
Stefan Krah0e803b32010-11-26 16:16:47 +00002859 oname = PyBytes_FromString(".");
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002860 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002861 name = PyBytes_AsString(oname);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002862 Py_BEGIN_ALLOW_THREADS
2863 dirp = opendir(name);
2864 Py_END_ALLOW_THREADS
2865 if (dirp == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002866 return posix_error_with_allocated_filename(oname);
2867 }
2868 if ((d = PyList_New(0)) == NULL) {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002869 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002870 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002871 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002872 Py_DECREF(oname);
2873 return NULL;
2874 }
2875 for (;;) {
2876 errno = 0;
2877 Py_BEGIN_ALLOW_THREADS
2878 ep = readdir(dirp);
2879 Py_END_ALLOW_THREADS
2880 if (ep == NULL) {
2881 if (errno == 0) {
2882 break;
2883 } else {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002884 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002885 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002886 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002887 Py_DECREF(d);
2888 return posix_error_with_allocated_filename(oname);
2889 }
2890 }
2891 if (ep->d_name[0] == '.' &&
2892 (NAMLEN(ep) == 1 ||
2893 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2894 continue;
Victor Stinnera45598a2010-05-14 16:35:39 +00002895 if (arg_is_unicode)
2896 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2897 else
2898 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00002899 if (v == NULL) {
Victor Stinnera45598a2010-05-14 16:35:39 +00002900 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002901 break;
2902 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002903 if (PyList_Append(d, v) != 0) {
2904 Py_DECREF(v);
Victor Stinnera45598a2010-05-14 16:35:39 +00002905 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002906 break;
2907 }
2908 Py_DECREF(v);
2909 }
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002910 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002911 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002912 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002913 Py_DECREF(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002914
Victor Stinner8c62be82010-05-06 00:08:46 +00002915 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002916
Tim Peters0bb44a42000-09-15 07:44:49 +00002917#endif /* which OS */
2918} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002919
Antoine Pitrou8250e232011-02-25 23:41:16 +00002920#ifdef HAVE_FDOPENDIR
Charles-François Natali77940902012-02-06 19:54:48 +01002921PyDoc_STRVAR(posix_flistdir__doc__,
2922"flistdir(fd) -> list_of_strings\n\n\
Charles-François Natali76961fa2012-01-10 20:25:09 +01002923Like listdir(), but uses a file descriptor instead.");
Antoine Pitrou8250e232011-02-25 23:41:16 +00002924
2925static PyObject *
Charles-François Natali77940902012-02-06 19:54:48 +01002926posix_flistdir(PyObject *self, PyObject *args)
Antoine Pitrou8250e232011-02-25 23:41:16 +00002927{
2928 PyObject *d, *v;
2929 DIR *dirp;
2930 struct dirent *ep;
2931 int fd;
2932
2933 errno = 0;
Charles-François Natali77940902012-02-06 19:54:48 +01002934 if (!PyArg_ParseTuple(args, "i:flistdir", &fd))
Antoine Pitrou8250e232011-02-25 23:41:16 +00002935 return NULL;
Charles-François Natali76961fa2012-01-10 20:25:09 +01002936 /* closedir() closes the FD, so we duplicate it */
2937 fd = dup(fd);
2938 if (fd < 0)
2939 return posix_error();
Antoine Pitrou8250e232011-02-25 23:41:16 +00002940 Py_BEGIN_ALLOW_THREADS
2941 dirp = fdopendir(fd);
2942 Py_END_ALLOW_THREADS
2943 if (dirp == NULL) {
2944 close(fd);
2945 return posix_error();
2946 }
2947 if ((d = PyList_New(0)) == NULL) {
2948 Py_BEGIN_ALLOW_THREADS
2949 closedir(dirp);
2950 Py_END_ALLOW_THREADS
2951 return NULL;
2952 }
2953 for (;;) {
2954 errno = 0;
2955 Py_BEGIN_ALLOW_THREADS
2956 ep = readdir(dirp);
2957 Py_END_ALLOW_THREADS
2958 if (ep == NULL) {
2959 if (errno == 0) {
2960 break;
2961 } else {
2962 Py_BEGIN_ALLOW_THREADS
Charles-François Natalif2840a82012-01-08 20:30:47 +01002963 rewinddir(dirp);
Antoine Pitrou8250e232011-02-25 23:41:16 +00002964 closedir(dirp);
2965 Py_END_ALLOW_THREADS
2966 Py_DECREF(d);
2967 return posix_error();
2968 }
2969 }
2970 if (ep->d_name[0] == '.' &&
2971 (NAMLEN(ep) == 1 ||
2972 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2973 continue;
2974 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2975 if (v == NULL) {
2976 Py_CLEAR(d);
2977 break;
2978 }
2979 if (PyList_Append(d, v) != 0) {
2980 Py_DECREF(v);
2981 Py_CLEAR(d);
2982 break;
2983 }
2984 Py_DECREF(v);
2985 }
2986 Py_BEGIN_ALLOW_THREADS
Charles-François Natalif2840a82012-01-08 20:30:47 +01002987 rewinddir(dirp);
Antoine Pitrou8250e232011-02-25 23:41:16 +00002988 closedir(dirp);
2989 Py_END_ALLOW_THREADS
2990
2991 return d;
2992}
2993#endif
2994
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002995#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002996/* A helper function for abspath on win32 */
2997static PyObject *
2998posix__getfullpathname(PyObject *self, PyObject *args)
2999{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003000 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003001 char outbuf[MAX_PATH*2];
3002 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003003 PyObject *po;
3004
3005 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3006 {
3007 wchar_t *wpath;
3008 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3009 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003010 DWORD result;
3011 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003012
3013 wpath = PyUnicode_AsUnicode(po);
3014 if (wpath == NULL)
3015 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003016 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003017 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003018 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003019 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003020 woutbufp = malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003021 if (!woutbufp)
3022 return PyErr_NoMemory();
3023 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3024 }
3025 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003026 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003027 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003028 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003029 if (woutbufp != woutbuf)
3030 free(woutbufp);
3031 return v;
3032 }
3033 /* Drop the argument parsing error as narrow strings
3034 are also valid. */
3035 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003036
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003037 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3038 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003039 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003040 if (win32_warn_bytes_api())
3041 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003042 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003043 outbuf, &temp)) {
3044 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003045 return NULL;
3046 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003047 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3048 return PyUnicode_Decode(outbuf, strlen(outbuf),
3049 Py_FileSystemDefaultEncoding, NULL);
3050 }
3051 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003052} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003053
Brian Curtind25aef52011-06-13 15:16:04 -05003054
Brian Curtinf5e76d02010-11-24 13:14:05 +00003055
Brian Curtind40e6f72010-07-08 21:39:08 +00003056/* A helper function for samepath on windows */
3057static PyObject *
3058posix__getfinalpathname(PyObject *self, PyObject *args)
3059{
3060 HANDLE hFile;
3061 int buf_size;
3062 wchar_t *target_path;
3063 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003064 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003065 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003066
Victor Stinnereb5657a2011-09-30 01:44:27 +02003067 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003068 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003069 path = PyUnicode_AsUnicode(po);
3070 if (path == NULL)
3071 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003072
3073 if(!check_GetFinalPathNameByHandle()) {
3074 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3075 NotImplementedError. */
3076 return PyErr_Format(PyExc_NotImplementedError,
3077 "GetFinalPathNameByHandle not available on this platform");
3078 }
3079
3080 hFile = CreateFileW(
3081 path,
3082 0, /* desired access */
3083 0, /* share mode */
3084 NULL, /* security attributes */
3085 OPEN_EXISTING,
3086 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3087 FILE_FLAG_BACKUP_SEMANTICS,
3088 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003089
Victor Stinnereb5657a2011-09-30 01:44:27 +02003090 if(hFile == INVALID_HANDLE_VALUE)
3091 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003092
3093 /* We have a good handle to the target, use it to determine the
3094 target path name. */
3095 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3096
3097 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003098 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003099
3100 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
3101 if(!target_path)
3102 return PyErr_NoMemory();
3103
3104 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3105 buf_size, VOLUME_NAME_DOS);
3106 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003107 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003108
3109 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003110 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003111
3112 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003113 result = PyUnicode_FromWideChar(target_path, result_length);
Brian Curtind40e6f72010-07-08 21:39:08 +00003114 free(target_path);
3115 return result;
3116
3117} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003118
3119static PyObject *
3120posix__getfileinformation(PyObject *self, PyObject *args)
3121{
3122 HANDLE hFile;
3123 BY_HANDLE_FILE_INFORMATION info;
3124 int fd;
3125
3126 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
3127 return NULL;
3128
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003129 if (!_PyVerify_fd(fd))
3130 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003131
3132 hFile = (HANDLE)_get_osfhandle(fd);
3133 if (hFile == INVALID_HANDLE_VALUE)
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003134 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003135
3136 if (!GetFileInformationByHandle(hFile, &info))
3137 return win32_error("_getfileinformation", NULL);
3138
3139 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
3140 info.nFileIndexHigh,
3141 info.nFileIndexLow);
3142}
Brian Curtin9c669cc2011-06-08 18:17:18 -05003143
Brian Curtin95d028f2011-06-09 09:10:38 -05003144PyDoc_STRVAR(posix__isdir__doc__,
3145"Return true if the pathname refers to an existing directory.");
3146
Brian Curtin9c669cc2011-06-08 18:17:18 -05003147static PyObject *
3148posix__isdir(PyObject *self, PyObject *args)
3149{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003150 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003151 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003152 DWORD attributes;
3153
3154 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003155 wchar_t *wpath = PyUnicode_AsUnicode(po);
3156 if (wpath == NULL)
3157 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003158
3159 attributes = GetFileAttributesW(wpath);
3160 if (attributes == INVALID_FILE_ATTRIBUTES)
3161 Py_RETURN_FALSE;
3162 goto check;
3163 }
3164 /* Drop the argument parsing error as narrow strings
3165 are also valid. */
3166 PyErr_Clear();
3167
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003168 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003169 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003170 if (win32_warn_bytes_api())
3171 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003172 attributes = GetFileAttributesA(path);
3173 if (attributes == INVALID_FILE_ATTRIBUTES)
3174 Py_RETURN_FALSE;
3175
3176check:
3177 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3178 Py_RETURN_TRUE;
3179 else
3180 Py_RETURN_FALSE;
3181}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003182#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003183
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003184PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003185"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003186Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003187
Barry Warsaw53699e91996-12-10 23:23:01 +00003188static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003189posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003190{
Victor Stinner8c62be82010-05-06 00:08:46 +00003191 int res;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003192 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003193 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003194
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003195#ifdef MS_WINDOWS
Victor Stinnereb5657a2011-09-30 01:44:27 +02003196 PyObject *po;
3197 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode))
3198 {
3199 wchar_t *wpath = PyUnicode_AsUnicode(po);
3200 if (wpath == NULL)
3201 return NULL;
3202
Victor Stinner8c62be82010-05-06 00:08:46 +00003203 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02003204 res = CreateDirectoryW(wpath, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003205 Py_END_ALLOW_THREADS
3206 if (!res)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003207 return win32_error_object("mkdir", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003208 Py_INCREF(Py_None);
3209 return Py_None;
3210 }
3211 /* Drop the argument parsing error as narrow strings
3212 are also valid. */
3213 PyErr_Clear();
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003214 if (!PyArg_ParseTuple(args, "y|i:mkdir", &path, &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00003215 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003216 if (win32_warn_bytes_api())
3217 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003218 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003219 res = CreateDirectoryA(path, NULL);
3220 Py_END_ALLOW_THREADS
3221 if (!res) {
3222 win32_error("mkdir", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003223 return NULL;
3224 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003225 Py_INCREF(Py_None);
3226 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003227#else
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003228 PyObject *opath;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003229
Victor Stinner8c62be82010-05-06 00:08:46 +00003230 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
3231 PyUnicode_FSConverter, &opath, &mode))
3232 return NULL;
3233 path = PyBytes_AsString(opath);
3234 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00003235#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinner8c62be82010-05-06 00:08:46 +00003236 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003237#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003238 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003239#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003240 Py_END_ALLOW_THREADS
3241 if (res < 0)
3242 return posix_error_with_allocated_filename(opath);
3243 Py_DECREF(opath);
3244 Py_INCREF(Py_None);
3245 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003246#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003247}
3248
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003249
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003250/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3251#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003252#include <sys/resource.h>
3253#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003254
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003255
3256#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003257PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003258"nice(inc) -> new_priority\n\n\
3259Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003260
Barry Warsaw53699e91996-12-10 23:23:01 +00003261static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003262posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00003263{
Victor Stinner8c62be82010-05-06 00:08:46 +00003264 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00003265
Victor Stinner8c62be82010-05-06 00:08:46 +00003266 if (!PyArg_ParseTuple(args, "i:nice", &increment))
3267 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003268
Victor Stinner8c62be82010-05-06 00:08:46 +00003269 /* There are two flavours of 'nice': one that returns the new
3270 priority (as required by almost all standards out there) and the
3271 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3272 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003273
Victor Stinner8c62be82010-05-06 00:08:46 +00003274 If we are of the nice family that returns the new priority, we
3275 need to clear errno before the call, and check if errno is filled
3276 before calling posix_error() on a returnvalue of -1, because the
3277 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003278
Victor Stinner8c62be82010-05-06 00:08:46 +00003279 errno = 0;
3280 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003281#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003282 if (value == 0)
3283 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003284#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003285 if (value == -1 && errno != 0)
3286 /* either nice() or getpriority() returned an error */
3287 return posix_error();
3288 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003289}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003290#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003291
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003292
3293#ifdef HAVE_GETPRIORITY
3294PyDoc_STRVAR(posix_getpriority__doc__,
3295"getpriority(which, who) -> current_priority\n\n\
3296Get program scheduling priority.");
3297
3298static PyObject *
3299posix_getpriority(PyObject *self, PyObject *args)
3300{
3301 int which, who, retval;
3302
3303 if (!PyArg_ParseTuple(args, "ii", &which, &who))
3304 return NULL;
3305 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003306 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003307 if (errno != 0)
3308 return posix_error();
3309 return PyLong_FromLong((long)retval);
3310}
3311#endif /* HAVE_GETPRIORITY */
3312
3313
3314#ifdef HAVE_SETPRIORITY
3315PyDoc_STRVAR(posix_setpriority__doc__,
3316"setpriority(which, who, prio) -> None\n\n\
3317Set program scheduling priority.");
3318
3319static PyObject *
3320posix_setpriority(PyObject *self, PyObject *args)
3321{
3322 int which, who, prio, retval;
3323
3324 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
3325 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003326 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003327 if (retval == -1)
3328 return posix_error();
3329 Py_RETURN_NONE;
3330}
3331#endif /* HAVE_SETPRIORITY */
3332
3333
Barry Warsaw53699e91996-12-10 23:23:01 +00003334static PyObject *
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003335internal_rename(PyObject *self, PyObject *args, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003336{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003337#ifdef MS_WINDOWS
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003338 PyObject *src, *dst;
Victor Stinner8c62be82010-05-06 00:08:46 +00003339 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003340 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
3341 if (PyArg_ParseTuple(args,
3342 is_replace ? "UU:replace" : "UU:rename",
3343 &src, &dst))
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003344 {
3345 wchar_t *wsrc, *wdst;
3346
3347 wsrc = PyUnicode_AsUnicode(src);
3348 if (wsrc == NULL)
3349 return NULL;
3350 wdst = PyUnicode_AsUnicode(dst);
3351 if (wdst == NULL)
3352 return NULL;
3353 Py_BEGIN_ALLOW_THREADS
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003354 result = MoveFileExW(wsrc, wdst, flags);
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003355 Py_END_ALLOW_THREADS
3356 if (!result)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003357 return win32_error(is_replace ? "replace" : "rename", NULL);
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003358 Py_INCREF(Py_None);
3359 return Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003360 }
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003361 else {
3362 PyErr_Clear();
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003363 if (!PyArg_ParseTuple(args,
3364 is_replace ? "O&O&:replace" : "O&O&:rename",
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003365 PyUnicode_FSConverter, &src,
3366 PyUnicode_FSConverter, &dst))
3367 return NULL;
3368
3369 if (win32_warn_bytes_api())
3370 goto error;
3371
3372 Py_BEGIN_ALLOW_THREADS
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003373 result = MoveFileExA(PyBytes_AS_STRING(src),
3374 PyBytes_AS_STRING(dst), flags);
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003375 Py_END_ALLOW_THREADS
3376
3377 Py_XDECREF(src);
3378 Py_XDECREF(dst);
3379
3380 if (!result)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003381 return win32_error(is_replace ? "replace" : "rename", NULL);
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003382 Py_INCREF(Py_None);
3383 return Py_None;
3384
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003385error:
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003386 Py_XDECREF(src);
3387 Py_XDECREF(dst);
Victor Stinner8c62be82010-05-06 00:08:46 +00003388 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003389 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003390#else
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003391 return posix_2str(args,
3392 is_replace ? "O&O&:replace" : "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003393#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003394}
3395
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003396PyDoc_STRVAR(posix_rename__doc__,
3397"rename(old, new)\n\n\
3398Rename a file or directory.");
3399
3400static PyObject *
3401posix_rename(PyObject *self, PyObject *args)
3402{
3403 return internal_rename(self, args, 0);
3404}
3405
3406PyDoc_STRVAR(posix_replace__doc__,
3407"replace(old, new)\n\n\
3408Rename a file or directory, overwriting the destination.");
3409
3410static PyObject *
3411posix_replace(PyObject *self, PyObject *args)
3412{
3413 return internal_rename(self, args, 1);
3414}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003415
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003416PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003417"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003418Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003419
Barry Warsaw53699e91996-12-10 23:23:01 +00003420static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003421posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003422{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003423#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003424 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003425#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003426 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003427#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003428}
3429
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003430
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003431PyDoc_STRVAR(posix_stat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01003432"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003433Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003434
Barry Warsaw53699e91996-12-10 23:23:01 +00003435static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01003436posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003437{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003438#ifdef MS_WINDOWS
Victor Stinner4195b5c2012-02-08 23:03:19 +01003439 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_stat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003440#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01003441 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003442#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003443}
3444
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003445
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003446#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003447PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003448"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003449Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003450
Barry Warsaw53699e91996-12-10 23:23:01 +00003451static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003452posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003453{
Victor Stinner8c62be82010-05-06 00:08:46 +00003454 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00003455#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003456 wchar_t *command;
3457 if (!PyArg_ParseTuple(args, "u:system", &command))
3458 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003459
Victor Stinner8c62be82010-05-06 00:08:46 +00003460 Py_BEGIN_ALLOW_THREADS
3461 sts = _wsystem(command);
3462 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00003463#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003464 PyObject *command_obj;
3465 char *command;
3466 if (!PyArg_ParseTuple(args, "O&:system",
3467 PyUnicode_FSConverter, &command_obj))
3468 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003469
Victor Stinner8c62be82010-05-06 00:08:46 +00003470 command = PyBytes_AsString(command_obj);
3471 Py_BEGIN_ALLOW_THREADS
3472 sts = system(command);
3473 Py_END_ALLOW_THREADS
3474 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00003475#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003476 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003477}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003478#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003479
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003480
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003481PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003482"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003483Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003484
Barry Warsaw53699e91996-12-10 23:23:01 +00003485static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003486posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003487{
Victor Stinner8c62be82010-05-06 00:08:46 +00003488 int i;
3489 if (!PyArg_ParseTuple(args, "i:umask", &i))
3490 return NULL;
3491 i = (int)umask(i);
3492 if (i < 0)
3493 return posix_error();
3494 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003495}
3496
Brian Curtind40e6f72010-07-08 21:39:08 +00003497#ifdef MS_WINDOWS
3498
3499/* override the default DeleteFileW behavior so that directory
3500symlinks can be removed with this function, the same as with
3501Unix symlinks */
3502BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
3503{
3504 WIN32_FILE_ATTRIBUTE_DATA info;
3505 WIN32_FIND_DATAW find_data;
3506 HANDLE find_data_handle;
3507 int is_directory = 0;
3508 int is_link = 0;
3509
3510 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
3511 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003512
Brian Curtind40e6f72010-07-08 21:39:08 +00003513 /* Get WIN32_FIND_DATA structure for the path to determine if
3514 it is a symlink */
3515 if(is_directory &&
3516 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
3517 find_data_handle = FindFirstFileW(lpFileName, &find_data);
3518
3519 if(find_data_handle != INVALID_HANDLE_VALUE) {
3520 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
3521 FindClose(find_data_handle);
3522 }
3523 }
3524 }
3525
3526 if (is_directory && is_link)
3527 return RemoveDirectoryW(lpFileName);
3528
3529 return DeleteFileW(lpFileName);
3530}
3531#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003532
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003533PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003534"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003535Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003536
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003537PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003538"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003539Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003540
Barry Warsaw53699e91996-12-10 23:23:01 +00003541static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003542posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003543{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003544#ifdef MS_WINDOWS
Brian Curtin74e45612010-07-09 15:58:59 +00003545 return win32_1str(args, "remove", "y:remove", DeleteFileA,
3546 "U:remove", Py_DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003547#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003548 return posix_1str(args, "O&:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003549#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003550}
3551
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003552
Guido van Rossumb6775db1994-08-01 11:34:53 +00003553#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003554PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003555"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003556Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003557
Barry Warsaw53699e91996-12-10 23:23:01 +00003558static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003559posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003560{
Victor Stinner8c62be82010-05-06 00:08:46 +00003561 struct utsname u;
3562 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00003563
Victor Stinner8c62be82010-05-06 00:08:46 +00003564 Py_BEGIN_ALLOW_THREADS
3565 res = uname(&u);
3566 Py_END_ALLOW_THREADS
3567 if (res < 0)
3568 return posix_error();
3569 return Py_BuildValue("(sssss)",
3570 u.sysname,
3571 u.nodename,
3572 u.release,
3573 u.version,
3574 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003575}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003576#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003577
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003578
Larry Hastings76ad59b2012-05-03 00:30:07 -07003579static int
3580split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
3581{
3582 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04003583 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07003584 divmod = PyNumber_Divmod(py_long, billion);
3585 if (!divmod)
3586 goto exit;
3587 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
3588 if ((*s == -1) && PyErr_Occurred())
3589 goto exit;
3590 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04003591 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07003592 goto exit;
3593
3594 result = 1;
3595exit:
3596 Py_XDECREF(divmod);
3597 return result;
3598}
3599
3600
3601typedef int (*parameter_converter_t)(PyObject *, void *);
3602
3603typedef struct {
3604 /* input only */
3605 char path_format;
3606 parameter_converter_t converter;
3607 char *function_name;
3608 char *first_argument_name;
3609 PyObject *args;
3610 PyObject *kwargs;
3611
Victor Stinner034d0aa2012-06-05 01:22:15 +02003612 /* input/output */
Larry Hastings76ad59b2012-05-03 00:30:07 -07003613 PyObject **path;
3614
3615 /* output only */
3616 int now;
3617 time_t atime_s;
3618 long atime_ns;
3619 time_t mtime_s;
3620 long mtime_ns;
3621} utime_arguments;
3622
3623#define DECLARE_UA(ua, fname) \
3624 utime_arguments ua; \
3625 memset(&ua, 0, sizeof(ua)); \
3626 ua.function_name = fname; \
3627 ua.args = args; \
3628 ua.kwargs = kwargs; \
3629 ua.first_argument_name = "path"; \
3630
3631/* UA_TO_FILETIME doesn't declare atime and mtime for you */
3632#define UA_TO_FILETIME(ua, atime, mtime) \
3633 time_t_to_FILE_TIME(ua.atime_s, ua.atime_ns, &atime); \
3634 time_t_to_FILE_TIME(ua.mtime_s, ua.mtime_ns, &mtime)
3635
3636/* the rest of these macros declare the output variable for you */
3637#define UA_TO_TIMESPEC(ua, ts) \
3638 struct timespec ts[2]; \
3639 ts[0].tv_sec = ua.atime_s; \
3640 ts[0].tv_nsec = ua.atime_ns; \
3641 ts[1].tv_sec = ua.mtime_s; \
3642 ts[1].tv_nsec = ua.mtime_ns
3643
3644#define UA_TO_TIMEVAL(ua, tv) \
3645 struct timeval tv[2]; \
3646 tv[0].tv_sec = ua.atime_s; \
3647 tv[0].tv_usec = ua.atime_ns / 1000; \
3648 tv[1].tv_sec = ua.mtime_s; \
3649 tv[1].tv_usec = ua.mtime_ns / 1000
3650
3651#define UA_TO_UTIMBUF(ua, u) \
3652 struct utimbuf u; \
3653 utimbuf.actime = ua.atime_s; \
3654 utimbuf.modtime = ua.mtime_s
3655
3656#define UA_TO_TIME_T(ua, timet) \
3657 time_t timet[2]; \
3658 timet[0] = ua.atime_s; \
3659 timet[1] = ua.mtime_s
3660
3661
Victor Stinner034d0aa2012-06-05 01:22:15 +02003662/*
Larry Hastings76ad59b2012-05-03 00:30:07 -07003663 * utime_read_time_arguments() processes arguments for the utime
3664 * family of functions.
Larry Hastings76ad59b2012-05-03 00:30:07 -07003665 */
Larry Hastingsb3336402012-05-04 02:31:57 -07003666
3667typedef enum {
Benjamin Peterson9242c132012-05-25 10:26:47 -07003668 UTIME_SUCCESS = 0,
3669 UTIME_PARSE_FAILURE = 1,
3670 UTIME_TIMES_AND_NS_COLLISION = 2,
3671 UTIME_TIMES_CONVERSION_FAILURE = 3,
3672 UTIME_NS_CONVERSION_FAILURE = 4,
Larry Hastingsb3336402012-05-04 02:31:57 -07003673} utime_status;
3674
3675static utime_status
Larry Hastings76ad59b2012-05-03 00:30:07 -07003676utime_read_time_arguments(utime_arguments *ua)
3677{
3678 PyObject *times = NULL;
3679 PyObject *ns = NULL;
3680 char format[24];
3681 char *kwlist[4];
3682 char **kw = kwlist;
Larry Hastingsb3336402012-05-04 02:31:57 -07003683 utime_status return_value;
3684 int parse_result;
Larry Hastings76ad59b2012-05-03 00:30:07 -07003685
3686 *kw++ = ua->first_argument_name;
3687 *kw++ = "times";
3688 *kw++ = "ns";
3689 *kw = NULL;
3690
3691 sprintf(format, "%c%s|O$O:%s",
3692 ua->path_format,
3693 ua->converter ? "&" : "",
3694 ua->function_name);
3695
3696 if (ua->converter)
Larry Hastingsb3336402012-05-04 02:31:57 -07003697 parse_result = PyArg_ParseTupleAndKeywords(ua->args, ua->kwargs,
Larry Hastings76ad59b2012-05-03 00:30:07 -07003698 format, kwlist, ua->converter, ua->path, &times, &ns);
3699 else
Larry Hastingsb3336402012-05-04 02:31:57 -07003700 parse_result = PyArg_ParseTupleAndKeywords(ua->args, ua->kwargs,
Larry Hastings76ad59b2012-05-03 00:30:07 -07003701 format, kwlist, ua->path, &times, &ns);
3702
Larry Hastingsb3336402012-05-04 02:31:57 -07003703 if (!parse_result)
Benjamin Peterson9242c132012-05-25 10:26:47 -07003704 return UTIME_PARSE_FAILURE;
Larry Hastings76ad59b2012-05-03 00:30:07 -07003705
3706 if (times && ns) {
3707 PyErr_Format(PyExc_RuntimeError,
3708 "%s: you may specify either 'times'"
3709 " or 'ns' but not both",
3710 ua->function_name);
Benjamin Peterson9242c132012-05-25 10:26:47 -07003711 return_value = UTIME_TIMES_AND_NS_COLLISION;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04003712 goto fail;
Larry Hastings76ad59b2012-05-03 00:30:07 -07003713 }
3714
3715 if (times && (times != Py_None)) {
3716 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
3717 PyErr_Format(PyExc_TypeError,
Stefan Krah6b03f2c2012-05-05 22:37:05 +02003718 "%s: 'times' must be either"
Benjamin Peterson9bd9d742012-05-04 01:42:41 -04003719 " a tuple of two ints or None",
Larry Hastings76ad59b2012-05-03 00:30:07 -07003720 ua->function_name);
Benjamin Peterson9242c132012-05-25 10:26:47 -07003721 return_value = UTIME_TIMES_CONVERSION_FAILURE;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04003722 goto fail;
Larry Hastings76ad59b2012-05-03 00:30:07 -07003723 }
3724 ua->now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04003725 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
3726 &ua->atime_s, &ua->atime_ns) == -1 ||
3727 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Larry Hastingsb3336402012-05-04 02:31:57 -07003728 &ua->mtime_s, &ua->mtime_ns) == -1) {
Benjamin Peterson9242c132012-05-25 10:26:47 -07003729 return_value = UTIME_TIMES_CONVERSION_FAILURE;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04003730 goto fail;
Larry Hastingsb3336402012-05-04 02:31:57 -07003731 }
Benjamin Peterson9242c132012-05-25 10:26:47 -07003732 return UTIME_SUCCESS;
Larry Hastings76ad59b2012-05-03 00:30:07 -07003733 }
3734
3735 if (ns) {
3736 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
3737 PyErr_Format(PyExc_TypeError,
Benjamin Peterson9bd9d742012-05-04 01:42:41 -04003738 "%s: 'ns' must be a tuple of two ints",
Larry Hastings76ad59b2012-05-03 00:30:07 -07003739 ua->function_name);
Benjamin Peterson9242c132012-05-25 10:26:47 -07003740 return_value = UTIME_NS_CONVERSION_FAILURE;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04003741 goto fail;
Larry Hastings76ad59b2012-05-03 00:30:07 -07003742 }
3743 ua->now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04003744 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
3745 &ua->atime_s, &ua->atime_ns) ||
3746 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastingsb3336402012-05-04 02:31:57 -07003747 &ua->mtime_s, &ua->mtime_ns)) {
Benjamin Peterson9242c132012-05-25 10:26:47 -07003748 return_value = UTIME_NS_CONVERSION_FAILURE;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04003749 goto fail;
Larry Hastingsb3336402012-05-04 02:31:57 -07003750 }
Benjamin Peterson9242c132012-05-25 10:26:47 -07003751 return UTIME_SUCCESS;
Larry Hastings76ad59b2012-05-03 00:30:07 -07003752 }
3753
3754 /* either times=None, or neither times nor ns was specified. use "now". */
3755 ua->now = 1;
Benjamin Peterson9242c132012-05-25 10:26:47 -07003756 return UTIME_SUCCESS;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04003757
3758 fail:
3759 if (ua->converter)
Richard Oudkerkf072b452012-05-04 12:01:31 +01003760 Py_DECREF(*ua->path);
Larry Hastingsb3336402012-05-04 02:31:57 -07003761 return return_value;
Larry Hastings76ad59b2012-05-03 00:30:07 -07003762}
3763
3764
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003765PyDoc_STRVAR(posix_utime__doc__,
Larry Hastings76ad59b2012-05-03 00:30:07 -07003766"utime(path[, times=(atime, mtime), *, ns=(atime_ns, mtime_ns)])\n\
3767Set the access and modified time of the file.\n\
3768If the second argument ('times') is specified,\n\
3769 the values should be expressed as float seconds since the epoch.\n\
3770If the keyword argument 'ns' is specified,\n\
3771 the values should be expressed as integer nanoseconds since the epoch.\n\
3772If neither the second nor the 'ns' argument is specified,\n\
3773 utime uses the current time.\n\
3774Specifying both 'times' and 'ns' is an error.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003775
Barry Warsaw53699e91996-12-10 23:23:01 +00003776static PyObject *
Larry Hastings76ad59b2012-05-03 00:30:07 -07003777posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003778{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003779#ifdef MS_WINDOWS
Larry Hastings76ad59b2012-05-03 00:30:07 -07003780 PyObject *upath;
Victor Stinner8c62be82010-05-06 00:08:46 +00003781 HANDLE hFile;
Victor Stinner8c62be82010-05-06 00:08:46 +00003782 PyObject *result = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07003783 FILETIME atime, mtime;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003784
Larry Hastings76ad59b2012-05-03 00:30:07 -07003785 DECLARE_UA(ua, "utime");
3786
3787 ua.path_format = 'U';
3788 ua.path = &upath;
3789
Larry Hastingsb3336402012-05-04 02:31:57 -07003790 switch (utime_read_time_arguments(&ua)) {
3791 default:
3792 return NULL;
Benjamin Peterson9242c132012-05-25 10:26:47 -07003793 case UTIME_SUCCESS: {
Larry Hastings76ad59b2012-05-03 00:30:07 -07003794 wchar_t *wpath = PyUnicode_AsUnicode(upath);
Victor Stinnereb5657a2011-09-30 01:44:27 +02003795 if (wpath == NULL)
3796 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003797 Py_BEGIN_ALLOW_THREADS
3798 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
3799 NULL, OPEN_EXISTING,
3800 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3801 Py_END_ALLOW_THREADS
3802 if (hFile == INVALID_HANDLE_VALUE)
Larry Hastings76ad59b2012-05-03 00:30:07 -07003803 return win32_error_object("utime", upath);
Larry Hastingsb3336402012-05-04 02:31:57 -07003804 break;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003805 }
Benjamin Peterson9242c132012-05-25 10:26:47 -07003806 case UTIME_PARSE_FAILURE: {
Larry Hastings76ad59b2012-05-03 00:30:07 -07003807 const char *apath;
Victor Stinner8c62be82010-05-06 00:08:46 +00003808 /* Drop the argument parsing error as narrow strings
3809 are also valid. */
3810 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003811
Larry Hastings76ad59b2012-05-03 00:30:07 -07003812 ua.path_format = 'y';
3813 ua.path = (PyObject **)&apath;
Benjamin Peterson9242c132012-05-25 10:26:47 -07003814 if (utime_read_time_arguments(&ua) != UTIME_SUCCESS)
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003815 return NULL;
3816 if (win32_warn_bytes_api())
Victor Stinner8c62be82010-05-06 00:08:46 +00003817 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003818
Victor Stinner8c62be82010-05-06 00:08:46 +00003819 Py_BEGIN_ALLOW_THREADS
3820 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
3821 NULL, OPEN_EXISTING,
3822 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3823 Py_END_ALLOW_THREADS
3824 if (hFile == INVALID_HANDLE_VALUE) {
3825 win32_error("utime", apath);
Victor Stinner8c62be82010-05-06 00:08:46 +00003826 return NULL;
3827 }
Larry Hastingsb3336402012-05-04 02:31:57 -07003828 break;
3829 }
3830
Victor Stinner8c62be82010-05-06 00:08:46 +00003831 }
3832
Larry Hastings76ad59b2012-05-03 00:30:07 -07003833 if (ua.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003834 SYSTEMTIME now;
3835 GetSystemTime(&now);
3836 if (!SystemTimeToFileTime(&now, &mtime) ||
3837 !SystemTimeToFileTime(&now, &atime)) {
3838 win32_error("utime", NULL);
3839 goto done;
Stefan Krah0e803b32010-11-26 16:16:47 +00003840 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003841 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003842 else {
Larry Hastings76ad59b2012-05-03 00:30:07 -07003843 UA_TO_FILETIME(ua, atime, mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00003844 }
3845 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3846 /* Avoid putting the file name into the error here,
3847 as that may confuse the user into believing that
3848 something is wrong with the file, when it also
3849 could be the time stamp that gives a problem. */
3850 win32_error("utime", NULL);
Antoine Pitroue85da7a2011-01-06 18:25:55 +00003851 goto done;
Victor Stinner8c62be82010-05-06 00:08:46 +00003852 }
3853 Py_INCREF(Py_None);
3854 result = Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003855done:
Victor Stinner8c62be82010-05-06 00:08:46 +00003856 CloseHandle(hFile);
3857 return result;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003858#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00003859 PyObject *opath;
3860 char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003861 int res;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003862
Larry Hastings76ad59b2012-05-03 00:30:07 -07003863 DECLARE_UA(ua, "utime");
3864
3865 ua.path_format = 'O';
3866 ua.path = &opath;
3867 ua.converter = PyUnicode_FSConverter;
3868
Benjamin Peterson9242c132012-05-25 10:26:47 -07003869 if (utime_read_time_arguments(&ua) != UTIME_SUCCESS)
Victor Stinner8c62be82010-05-06 00:08:46 +00003870 return NULL;
3871 path = PyBytes_AsString(opath);
Larry Hastings76ad59b2012-05-03 00:30:07 -07003872 if (ua.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003873 Py_BEGIN_ALLOW_THREADS
3874 res = utime(path, NULL);
3875 Py_END_ALLOW_THREADS
3876 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003877 else {
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003878 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003879#ifdef HAVE_UTIMENSAT
Larry Hastings76ad59b2012-05-03 00:30:07 -07003880 UA_TO_TIMESPEC(ua, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003881 res = utimensat(AT_FDCWD, path, buf, 0);
3882#elif defined(HAVE_UTIMES)
Larry Hastings76ad59b2012-05-03 00:30:07 -07003883 UA_TO_TIMEVAL(ua, buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003884 res = utimes(path, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003885#elif defined(HAVE_UTIME_H)
3886 /* XXX should define struct utimbuf instead, above */
Larry Hastings76ad59b2012-05-03 00:30:07 -07003887 UA_TO_UTIMBUF(ua, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003888 res = utime(path, &buf);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003889#else
Larry Hastings76ad59b2012-05-03 00:30:07 -07003890 UA_TO_TIME_T(ua, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003891 res = utime(path, buf);
3892#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003893 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003894 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07003895
Victor Stinner8c62be82010-05-06 00:08:46 +00003896 if (res < 0) {
3897 return posix_error_with_allocated_filename(opath);
3898 }
3899 Py_DECREF(opath);
Larry Hastings76ad59b2012-05-03 00:30:07 -07003900 Py_RETURN_NONE;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003901#undef UTIME_EXTRACT
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003902#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003903}
3904
Ross Lagerwall7807c352011-03-17 20:20:30 +02003905#ifdef HAVE_FUTIMES
3906PyDoc_STRVAR(posix_futimes__doc__,
Larry Hastings76ad59b2012-05-03 00:30:07 -07003907"futimes(fd[, times=(atime, mtime), *, ns=(atime_ns, mtime_ns)])\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003908Set the access and modified time of the file specified by the file\n\
Larry Hastings76ad59b2012-05-03 00:30:07 -07003909descriptor fd. See utime for the semantics of the times and ns parameters.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02003910
3911static PyObject *
Larry Hastings76ad59b2012-05-03 00:30:07 -07003912posix_futimes(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02003913{
3914 int res, fd;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003915
Larry Hastings76ad59b2012-05-03 00:30:07 -07003916 DECLARE_UA(ua, "futimes");
3917
3918 ua.path_format = 'i';
3919 ua.path = (PyObject **)&fd;
3920 ua.first_argument_name = "fd";
3921
Benjamin Peterson9242c132012-05-25 10:26:47 -07003922 if (utime_read_time_arguments(&ua) != UTIME_SUCCESS)
Ross Lagerwall7807c352011-03-17 20:20:30 +02003923 return NULL;
3924
Larry Hastings76ad59b2012-05-03 00:30:07 -07003925 if (ua.now) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003926 Py_BEGIN_ALLOW_THREADS
3927 res = futimes(fd, NULL);
3928 Py_END_ALLOW_THREADS
3929 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003930 else {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003931 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003932 {
3933#ifdef HAVE_FUTIMENS
Larry Hastings76ad59b2012-05-03 00:30:07 -07003934 UA_TO_TIMESPEC(ua, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003935 res = futimens(fd, buf);
3936#else
Larry Hastings76ad59b2012-05-03 00:30:07 -07003937 UA_TO_TIMEVAL(ua, buf);
Ross Lagerwall7807c352011-03-17 20:20:30 +02003938 res = futimes(fd, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003939#endif
3940 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003941 Py_END_ALLOW_THREADS
3942 }
3943 if (res < 0)
3944 return posix_error();
3945 Py_RETURN_NONE;
3946}
3947#endif
3948
3949#ifdef HAVE_LUTIMES
3950PyDoc_STRVAR(posix_lutimes__doc__,
Larry Hastings76ad59b2012-05-03 00:30:07 -07003951"lutimes(path[, times=(atime, mtime), *, ns=(atime_ns, mtime_ns)])\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003952Like utime(), but if path is a symbolic link, it is not dereferenced.");
3953
3954static PyObject *
Larry Hastings76ad59b2012-05-03 00:30:07 -07003955posix_lutimes(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02003956{
Brian Curtinc1b65d12011-11-07 14:18:54 -06003957 PyObject *opath;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003958 const char *path;
3959 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003960
Larry Hastings76ad59b2012-05-03 00:30:07 -07003961 DECLARE_UA(ua, "lutimes");
3962
3963 ua.path_format = 'O';
3964 ua.path = &opath;
3965 ua.converter = PyUnicode_FSConverter;
3966
Benjamin Peterson9242c132012-05-25 10:26:47 -07003967 if (utime_read_time_arguments(&ua) != UTIME_SUCCESS)
Ross Lagerwall7807c352011-03-17 20:20:30 +02003968 return NULL;
3969 path = PyBytes_AsString(opath);
Larry Hastings76ad59b2012-05-03 00:30:07 -07003970
3971 if (ua.now) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003972 /* optional time values not given */
3973 Py_BEGIN_ALLOW_THREADS
3974 res = lutimes(path, NULL);
3975 Py_END_ALLOW_THREADS
3976 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003977 else {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003978 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003979 {
3980#ifdef HAVE_UTIMENSAT
Larry Hastings76ad59b2012-05-03 00:30:07 -07003981 UA_TO_TIMESPEC(ua, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003982 res = utimensat(AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW);
3983#else
Larry Hastings76ad59b2012-05-03 00:30:07 -07003984 UA_TO_TIMEVAL(ua, buf);
Ross Lagerwall7807c352011-03-17 20:20:30 +02003985 res = lutimes(path, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003986#endif
3987 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003988 Py_END_ALLOW_THREADS
3989 }
3990 Py_DECREF(opath);
3991 if (res < 0)
3992 return posix_error();
3993 Py_RETURN_NONE;
3994}
3995#endif
3996
Guido van Rossum3b066191991-06-04 19:40:25 +00003997/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003998
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003999PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004000"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004001Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004002
Barry Warsaw53699e91996-12-10 23:23:01 +00004003static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004004posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004005{
Victor Stinner8c62be82010-05-06 00:08:46 +00004006 int sts;
4007 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
4008 return NULL;
4009 _exit(sts);
4010 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004011}
4012
Martin v. Löwis114619e2002-10-07 06:44:21 +00004013#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4014static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004015free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004016{
Victor Stinner8c62be82010-05-06 00:08:46 +00004017 Py_ssize_t i;
4018 for (i = 0; i < count; i++)
4019 PyMem_Free(array[i]);
4020 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004021}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004022
Antoine Pitrou69f71142009-05-24 21:25:49 +00004023static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004024int fsconvert_strdup(PyObject *o, char**out)
4025{
Victor Stinner8c62be82010-05-06 00:08:46 +00004026 PyObject *bytes;
4027 Py_ssize_t size;
4028 if (!PyUnicode_FSConverter(o, &bytes))
4029 return 0;
4030 size = PyBytes_GET_SIZE(bytes);
4031 *out = PyMem_Malloc(size+1);
4032 if (!*out)
4033 return 0;
4034 memcpy(*out, PyBytes_AsString(bytes), size+1);
4035 Py_DECREF(bytes);
4036 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004037}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004038#endif
4039
Ross Lagerwall7807c352011-03-17 20:20:30 +02004040#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004041static char**
4042parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4043{
Victor Stinner8c62be82010-05-06 00:08:46 +00004044 char **envlist;
4045 Py_ssize_t i, pos, envc;
4046 PyObject *keys=NULL, *vals=NULL;
4047 PyObject *key, *val, *key2, *val2;
4048 char *p, *k, *v;
4049 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004050
Victor Stinner8c62be82010-05-06 00:08:46 +00004051 i = PyMapping_Size(env);
4052 if (i < 0)
4053 return NULL;
4054 envlist = PyMem_NEW(char *, i + 1);
4055 if (envlist == NULL) {
4056 PyErr_NoMemory();
4057 return NULL;
4058 }
4059 envc = 0;
4060 keys = PyMapping_Keys(env);
4061 vals = PyMapping_Values(env);
4062 if (!keys || !vals)
4063 goto error;
4064 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4065 PyErr_Format(PyExc_TypeError,
4066 "env.keys() or env.values() is not a list");
4067 goto error;
4068 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004069
Victor Stinner8c62be82010-05-06 00:08:46 +00004070 for (pos = 0; pos < i; pos++) {
4071 key = PyList_GetItem(keys, pos);
4072 val = PyList_GetItem(vals, pos);
4073 if (!key || !val)
4074 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004075
Victor Stinner8c62be82010-05-06 00:08:46 +00004076 if (PyUnicode_FSConverter(key, &key2) == 0)
4077 goto error;
4078 if (PyUnicode_FSConverter(val, &val2) == 0) {
4079 Py_DECREF(key2);
4080 goto error;
4081 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004082
4083#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004084 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
4085 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00004086#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004087 k = PyBytes_AsString(key2);
4088 v = PyBytes_AsString(val2);
4089 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004090
Victor Stinner8c62be82010-05-06 00:08:46 +00004091 p = PyMem_NEW(char, len);
4092 if (p == NULL) {
4093 PyErr_NoMemory();
4094 Py_DECREF(key2);
4095 Py_DECREF(val2);
4096 goto error;
4097 }
4098 PyOS_snprintf(p, len, "%s=%s", k, v);
4099 envlist[envc++] = p;
4100 Py_DECREF(key2);
4101 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004102#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004103 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004104#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004105 }
4106 Py_DECREF(vals);
4107 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004108
Victor Stinner8c62be82010-05-06 00:08:46 +00004109 envlist[envc] = 0;
4110 *envc_ptr = envc;
4111 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004112
4113error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004114 Py_XDECREF(keys);
4115 Py_XDECREF(vals);
4116 while (--envc >= 0)
4117 PyMem_DEL(envlist[envc]);
4118 PyMem_DEL(envlist);
4119 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004120}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004121
Ross Lagerwall7807c352011-03-17 20:20:30 +02004122static char**
4123parse_arglist(PyObject* argv, Py_ssize_t *argc)
4124{
4125 int i;
4126 char **argvlist = PyMem_NEW(char *, *argc+1);
4127 if (argvlist == NULL) {
4128 PyErr_NoMemory();
4129 return NULL;
4130 }
4131 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004132 PyObject* item = PySequence_ITEM(argv, i);
4133 if (item == NULL)
4134 goto fail;
4135 if (!fsconvert_strdup(item, &argvlist[i])) {
4136 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004137 goto fail;
4138 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004139 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004140 }
4141 argvlist[*argc] = NULL;
4142 return argvlist;
4143fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004144 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004145 free_string_array(argvlist, *argc);
4146 return NULL;
4147}
4148#endif
4149
4150#ifdef HAVE_EXECV
4151PyDoc_STRVAR(posix_execv__doc__,
4152"execv(path, args)\n\n\
4153Execute an executable path with arguments, replacing current process.\n\
4154\n\
4155 path: path of executable file\n\
4156 args: tuple or list of strings");
4157
4158static PyObject *
4159posix_execv(PyObject *self, PyObject *args)
4160{
4161 PyObject *opath;
4162 char *path;
4163 PyObject *argv;
4164 char **argvlist;
4165 Py_ssize_t argc;
4166
4167 /* execv has two arguments: (path, argv), where
4168 argv is a list or tuple of strings. */
4169
4170 if (!PyArg_ParseTuple(args, "O&O:execv",
4171 PyUnicode_FSConverter,
4172 &opath, &argv))
4173 return NULL;
4174 path = PyBytes_AsString(opath);
4175 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4176 PyErr_SetString(PyExc_TypeError,
4177 "execv() arg 2 must be a tuple or list");
4178 Py_DECREF(opath);
4179 return NULL;
4180 }
4181 argc = PySequence_Size(argv);
4182 if (argc < 1) {
4183 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
4184 Py_DECREF(opath);
4185 return NULL;
4186 }
4187
4188 argvlist = parse_arglist(argv, &argc);
4189 if (argvlist == NULL) {
4190 Py_DECREF(opath);
4191 return NULL;
4192 }
4193
4194 execv(path, argvlist);
4195
4196 /* If we get here it's definitely an error */
4197
4198 free_string_array(argvlist, argc);
4199 Py_DECREF(opath);
4200 return posix_error();
4201}
4202
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004203PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004204"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004205Execute a path with arguments and environment, replacing current process.\n\
4206\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004207 path: path of executable file\n\
4208 args: tuple or list of arguments\n\
4209 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004210
Barry Warsaw53699e91996-12-10 23:23:01 +00004211static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004212posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004213{
Victor Stinner8c62be82010-05-06 00:08:46 +00004214 PyObject *opath;
4215 char *path;
4216 PyObject *argv, *env;
4217 char **argvlist;
4218 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004219 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004220
Victor Stinner8c62be82010-05-06 00:08:46 +00004221 /* execve has three arguments: (path, argv, env), where
4222 argv is a list or tuple of strings and env is a dictionary
4223 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004224
Victor Stinner8c62be82010-05-06 00:08:46 +00004225 if (!PyArg_ParseTuple(args, "O&OO:execve",
4226 PyUnicode_FSConverter,
4227 &opath, &argv, &env))
4228 return NULL;
4229 path = PyBytes_AsString(opath);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004230 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004231 PyErr_SetString(PyExc_TypeError,
4232 "execve() arg 2 must be a tuple or list");
4233 goto fail_0;
4234 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004235 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00004236 if (!PyMapping_Check(env)) {
4237 PyErr_SetString(PyExc_TypeError,
4238 "execve() arg 3 must be a mapping object");
4239 goto fail_0;
4240 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004241
Ross Lagerwall7807c352011-03-17 20:20:30 +02004242 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004243 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004244 goto fail_0;
4245 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004246
Victor Stinner8c62be82010-05-06 00:08:46 +00004247 envlist = parse_envlist(env, &envc);
4248 if (envlist == NULL)
4249 goto fail_1;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004250
Victor Stinner8c62be82010-05-06 00:08:46 +00004251 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00004252
Victor Stinner8c62be82010-05-06 00:08:46 +00004253 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004254
Victor Stinner8c62be82010-05-06 00:08:46 +00004255 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004256
Victor Stinner8c62be82010-05-06 00:08:46 +00004257 while (--envc >= 0)
4258 PyMem_DEL(envlist[envc]);
4259 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004260 fail_1:
Ross Lagerwall7807c352011-03-17 20:20:30 +02004261 free_string_array(argvlist, argc);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004262 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004263 Py_DECREF(opath);
4264 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004265}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004266#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004267
Ross Lagerwall7807c352011-03-17 20:20:30 +02004268#ifdef HAVE_FEXECVE
4269PyDoc_STRVAR(posix_fexecve__doc__,
4270"fexecve(fd, args, env)\n\n\
4271Execute the program specified by a file descriptor with arguments and\n\
4272environment, replacing the current process.\n\
4273\n\
4274 fd: file descriptor of executable\n\
4275 args: tuple or list of arguments\n\
4276 env: dictionary of strings mapping to strings");
4277
4278static PyObject *
4279posix_fexecve(PyObject *self, PyObject *args)
4280{
4281 int fd;
4282 PyObject *argv, *env;
4283 char **argvlist;
4284 char **envlist;
4285 Py_ssize_t argc, envc;
4286
4287 if (!PyArg_ParseTuple(args, "iOO:fexecve",
4288 &fd, &argv, &env))
4289 return NULL;
4290 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4291 PyErr_SetString(PyExc_TypeError,
4292 "fexecve() arg 2 must be a tuple or list");
4293 return NULL;
4294 }
4295 argc = PySequence_Size(argv);
4296 if (!PyMapping_Check(env)) {
4297 PyErr_SetString(PyExc_TypeError,
4298 "fexecve() arg 3 must be a mapping object");
4299 return NULL;
4300 }
4301
4302 argvlist = parse_arglist(argv, &argc);
4303 if (argvlist == NULL)
4304 return NULL;
4305
4306 envlist = parse_envlist(env, &envc);
4307 if (envlist == NULL)
4308 goto fail;
4309
4310 fexecve(fd, argvlist, envlist);
4311
4312 /* If we get here it's definitely an error */
4313
4314 (void) posix_error();
4315
4316 while (--envc >= 0)
4317 PyMem_DEL(envlist[envc]);
4318 PyMem_DEL(envlist);
4319 fail:
4320 free_string_array(argvlist, argc);
4321 return NULL;
4322}
4323#endif /* HAVE_FEXECVE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004324
Guido van Rossuma1065681999-01-25 23:20:23 +00004325#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004326PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004327"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004328Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004329\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004330 mode: mode of process creation\n\
4331 path: path of executable file\n\
4332 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004333
4334static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004335posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004336{
Victor Stinner8c62be82010-05-06 00:08:46 +00004337 PyObject *opath;
4338 char *path;
4339 PyObject *argv;
4340 char **argvlist;
4341 int mode, i;
4342 Py_ssize_t argc;
4343 Py_intptr_t spawnval;
4344 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00004345
Victor Stinner8c62be82010-05-06 00:08:46 +00004346 /* spawnv has three arguments: (mode, path, argv), where
4347 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004348
Victor Stinner8c62be82010-05-06 00:08:46 +00004349 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
4350 PyUnicode_FSConverter,
4351 &opath, &argv))
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 "spawnv() arg 2 must be a tuple or list");
4365 Py_DECREF(opath);
4366 return NULL;
4367 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004368
Victor Stinner8c62be82010-05-06 00:08:46 +00004369 argvlist = PyMem_NEW(char *, argc+1);
4370 if (argvlist == NULL) {
4371 Py_DECREF(opath);
4372 return PyErr_NoMemory();
4373 }
4374 for (i = 0; i < argc; i++) {
4375 if (!fsconvert_strdup((*getitem)(argv, i),
4376 &argvlist[i])) {
4377 free_string_array(argvlist, i);
4378 PyErr_SetString(
4379 PyExc_TypeError,
4380 "spawnv() arg 2 must contain only strings");
4381 Py_DECREF(opath);
4382 return NULL;
4383 }
4384 }
4385 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004386
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004387#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004388 Py_BEGIN_ALLOW_THREADS
4389 spawnval = spawnv(mode, path, argvlist);
4390 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004391#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004392 if (mode == _OLD_P_OVERLAY)
4393 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00004394
Victor Stinner8c62be82010-05-06 00:08:46 +00004395 Py_BEGIN_ALLOW_THREADS
4396 spawnval = _spawnv(mode, path, argvlist);
4397 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004398#endif
Tim Peters5aa91602002-01-30 05:46:57 +00004399
Victor Stinner8c62be82010-05-06 00:08:46 +00004400 free_string_array(argvlist, argc);
4401 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00004402
Victor Stinner8c62be82010-05-06 00:08:46 +00004403 if (spawnval == -1)
4404 return posix_error();
4405 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004406#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00004407 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004408#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004409 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004410#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00004411}
4412
4413
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004414PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004415"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004416Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004417\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004418 mode: mode of process creation\n\
4419 path: path of executable file\n\
4420 args: tuple or list of arguments\n\
4421 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004422
4423static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004424posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004425{
Victor Stinner8c62be82010-05-06 00:08:46 +00004426 PyObject *opath;
4427 char *path;
4428 PyObject *argv, *env;
4429 char **argvlist;
4430 char **envlist;
4431 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00004432 int mode;
4433 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00004434 Py_intptr_t spawnval;
4435 PyObject *(*getitem)(PyObject *, Py_ssize_t);
4436 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00004437
Victor Stinner8c62be82010-05-06 00:08:46 +00004438 /* spawnve has four arguments: (mode, path, argv, env), where
4439 argv is a list or tuple of strings and env is a dictionary
4440 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004441
Victor Stinner8c62be82010-05-06 00:08:46 +00004442 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
4443 PyUnicode_FSConverter,
4444 &opath, &argv, &env))
4445 return NULL;
4446 path = PyBytes_AsString(opath);
4447 if (PyList_Check(argv)) {
4448 argc = PyList_Size(argv);
4449 getitem = PyList_GetItem;
4450 }
4451 else if (PyTuple_Check(argv)) {
4452 argc = PyTuple_Size(argv);
4453 getitem = PyTuple_GetItem;
4454 }
4455 else {
4456 PyErr_SetString(PyExc_TypeError,
4457 "spawnve() arg 2 must be a tuple or list");
4458 goto fail_0;
4459 }
4460 if (!PyMapping_Check(env)) {
4461 PyErr_SetString(PyExc_TypeError,
4462 "spawnve() arg 3 must be a mapping object");
4463 goto fail_0;
4464 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004465
Victor Stinner8c62be82010-05-06 00:08:46 +00004466 argvlist = PyMem_NEW(char *, argc+1);
4467 if (argvlist == NULL) {
4468 PyErr_NoMemory();
4469 goto fail_0;
4470 }
4471 for (i = 0; i < argc; i++) {
4472 if (!fsconvert_strdup((*getitem)(argv, i),
4473 &argvlist[i]))
4474 {
4475 lastarg = i;
4476 goto fail_1;
4477 }
4478 }
4479 lastarg = argc;
4480 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004481
Victor Stinner8c62be82010-05-06 00:08:46 +00004482 envlist = parse_envlist(env, &envc);
4483 if (envlist == NULL)
4484 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00004485
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004486#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004487 Py_BEGIN_ALLOW_THREADS
4488 spawnval = spawnve(mode, path, argvlist, envlist);
4489 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004490#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004491 if (mode == _OLD_P_OVERLAY)
4492 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00004493
Victor Stinner8c62be82010-05-06 00:08:46 +00004494 Py_BEGIN_ALLOW_THREADS
4495 spawnval = _spawnve(mode, path, argvlist, envlist);
4496 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004497#endif
Tim Peters25059d32001-12-07 20:35:43 +00004498
Victor Stinner8c62be82010-05-06 00:08:46 +00004499 if (spawnval == -1)
4500 (void) posix_error();
4501 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004502#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00004503 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004504#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004505 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004506#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00004507
Victor Stinner8c62be82010-05-06 00:08:46 +00004508 while (--envc >= 0)
4509 PyMem_DEL(envlist[envc]);
4510 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004511 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00004512 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004513 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004514 Py_DECREF(opath);
4515 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00004516}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004517
4518/* OS/2 supports spawnvp & spawnvpe natively */
4519#if defined(PYOS_OS2)
4520PyDoc_STRVAR(posix_spawnvp__doc__,
4521"spawnvp(mode, file, args)\n\n\
4522Execute the program 'file' in a new process, using the environment\n\
4523search path to find the file.\n\
4524\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004525 mode: mode of process creation\n\
4526 file: executable file name\n\
4527 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004528
4529static PyObject *
4530posix_spawnvp(PyObject *self, PyObject *args)
4531{
Victor Stinner8c62be82010-05-06 00:08:46 +00004532 PyObject *opath;
4533 char *path;
4534 PyObject *argv;
4535 char **argvlist;
4536 int mode, i, argc;
4537 Py_intptr_t spawnval;
4538 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004539
Victor Stinner8c62be82010-05-06 00:08:46 +00004540 /* spawnvp has three arguments: (mode, path, argv), where
4541 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004542
Victor Stinner8c62be82010-05-06 00:08:46 +00004543 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
4544 PyUnicode_FSConverter,
4545 &opath, &argv))
4546 return NULL;
4547 path = PyBytes_AsString(opath);
4548 if (PyList_Check(argv)) {
4549 argc = PyList_Size(argv);
4550 getitem = PyList_GetItem;
4551 }
4552 else if (PyTuple_Check(argv)) {
4553 argc = PyTuple_Size(argv);
4554 getitem = PyTuple_GetItem;
4555 }
4556 else {
4557 PyErr_SetString(PyExc_TypeError,
4558 "spawnvp() arg 2 must be a tuple or list");
4559 Py_DECREF(opath);
4560 return NULL;
4561 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004562
Victor Stinner8c62be82010-05-06 00:08:46 +00004563 argvlist = PyMem_NEW(char *, argc+1);
4564 if (argvlist == NULL) {
4565 Py_DECREF(opath);
4566 return PyErr_NoMemory();
4567 }
4568 for (i = 0; i < argc; i++) {
4569 if (!fsconvert_strdup((*getitem)(argv, i),
4570 &argvlist[i])) {
4571 free_string_array(argvlist, i);
4572 PyErr_SetString(
4573 PyExc_TypeError,
4574 "spawnvp() arg 2 must contain only strings");
4575 Py_DECREF(opath);
4576 return NULL;
4577 }
4578 }
4579 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004580
Victor Stinner8c62be82010-05-06 00:08:46 +00004581 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004582#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004583 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004584#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004585 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004586#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004587 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004588
Victor Stinner8c62be82010-05-06 00:08:46 +00004589 free_string_array(argvlist, argc);
4590 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004591
Victor Stinner8c62be82010-05-06 00:08:46 +00004592 if (spawnval == -1)
4593 return posix_error();
4594 else
4595 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004596}
4597
4598
4599PyDoc_STRVAR(posix_spawnvpe__doc__,
4600"spawnvpe(mode, file, args, env)\n\n\
4601Execute the program 'file' in a new process, using the environment\n\
4602search path to find the file.\n\
4603\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004604 mode: mode of process creation\n\
4605 file: executable file name\n\
4606 args: tuple or list of arguments\n\
4607 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004608
4609static PyObject *
4610posix_spawnvpe(PyObject *self, PyObject *args)
4611{
Ross Lagerwalldcfde5a2011-11-04 07:09:14 +02004612 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00004613 char *path;
4614 PyObject *argv, *env;
4615 char **argvlist;
4616 char **envlist;
4617 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00004618 int mode;
4619 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00004620 Py_intptr_t spawnval;
4621 PyObject *(*getitem)(PyObject *, Py_ssize_t);
4622 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004623
Victor Stinner8c62be82010-05-06 00:08:46 +00004624 /* spawnvpe has four arguments: (mode, path, argv, env), where
4625 argv is a list or tuple of strings and env is a dictionary
4626 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004627
Victor Stinner8c62be82010-05-06 00:08:46 +00004628 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
4629 PyUnicode_FSConverter,
4630 &opath, &argv, &env))
4631 return NULL;
4632 path = PyBytes_AsString(opath);
4633 if (PyList_Check(argv)) {
4634 argc = PyList_Size(argv);
4635 getitem = PyList_GetItem;
4636 }
4637 else if (PyTuple_Check(argv)) {
4638 argc = PyTuple_Size(argv);
4639 getitem = PyTuple_GetItem;
4640 }
4641 else {
4642 PyErr_SetString(PyExc_TypeError,
4643 "spawnvpe() arg 2 must be a tuple or list");
4644 goto fail_0;
4645 }
4646 if (!PyMapping_Check(env)) {
4647 PyErr_SetString(PyExc_TypeError,
4648 "spawnvpe() arg 3 must be a mapping object");
4649 goto fail_0;
4650 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004651
Victor Stinner8c62be82010-05-06 00:08:46 +00004652 argvlist = PyMem_NEW(char *, argc+1);
4653 if (argvlist == NULL) {
4654 PyErr_NoMemory();
4655 goto fail_0;
4656 }
4657 for (i = 0; i < argc; i++) {
4658 if (!fsconvert_strdup((*getitem)(argv, i),
4659 &argvlist[i]))
4660 {
4661 lastarg = i;
4662 goto fail_1;
4663 }
4664 }
4665 lastarg = argc;
4666 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004667
Victor Stinner8c62be82010-05-06 00:08:46 +00004668 envlist = parse_envlist(env, &envc);
4669 if (envlist == NULL)
4670 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004671
Victor Stinner8c62be82010-05-06 00:08:46 +00004672 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004673#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004674 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004675#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004676 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004677#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004678 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004679
Victor Stinner8c62be82010-05-06 00:08:46 +00004680 if (spawnval == -1)
4681 (void) posix_error();
4682 else
4683 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004684
Victor Stinner8c62be82010-05-06 00:08:46 +00004685 while (--envc >= 0)
4686 PyMem_DEL(envlist[envc]);
4687 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004688 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00004689 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004690 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004691 Py_DECREF(opath);
4692 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004693}
4694#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00004695#endif /* HAVE_SPAWNV */
4696
4697
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004698#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004699PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004700"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004701Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
4702\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004703Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004704
4705static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004706posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004707{
Victor Stinner8c62be82010-05-06 00:08:46 +00004708 pid_t pid;
4709 int result = 0;
4710 _PyImport_AcquireLock();
4711 pid = fork1();
4712 if (pid == 0) {
4713 /* child: this clobbers and resets the import lock. */
4714 PyOS_AfterFork();
4715 } else {
4716 /* parent: release the import lock. */
4717 result = _PyImport_ReleaseLock();
4718 }
4719 if (pid == -1)
4720 return posix_error();
4721 if (result < 0) {
4722 /* Don't clobber the OSError if the fork failed. */
4723 PyErr_SetString(PyExc_RuntimeError,
4724 "not holding the import lock");
4725 return NULL;
4726 }
4727 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004728}
4729#endif
4730
4731
Guido van Rossumad0ee831995-03-01 10:34:45 +00004732#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004733PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004734"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004735Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004736Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004737
Barry Warsaw53699e91996-12-10 23:23:01 +00004738static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004739posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004740{
Victor Stinner8c62be82010-05-06 00:08:46 +00004741 pid_t pid;
4742 int result = 0;
4743 _PyImport_AcquireLock();
4744 pid = fork();
4745 if (pid == 0) {
4746 /* child: this clobbers and resets the import lock. */
4747 PyOS_AfterFork();
4748 } else {
4749 /* parent: release the import lock. */
4750 result = _PyImport_ReleaseLock();
4751 }
4752 if (pid == -1)
4753 return posix_error();
4754 if (result < 0) {
4755 /* Don't clobber the OSError if the fork failed. */
4756 PyErr_SetString(PyExc_RuntimeError,
4757 "not holding the import lock");
4758 return NULL;
4759 }
4760 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00004761}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004762#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004763
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004764#ifdef HAVE_SCHED_H
4765
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02004766#ifdef HAVE_SCHED_GET_PRIORITY_MAX
4767
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004768PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
4769"sched_get_priority_max(policy)\n\n\
4770Get the maximum scheduling priority for *policy*.");
4771
4772static PyObject *
4773posix_sched_get_priority_max(PyObject *self, PyObject *args)
4774{
4775 int policy, max;
4776
4777 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
4778 return NULL;
4779 max = sched_get_priority_max(policy);
4780 if (max < 0)
4781 return posix_error();
4782 return PyLong_FromLong(max);
4783}
4784
4785PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
4786"sched_get_priority_min(policy)\n\n\
4787Get the minimum scheduling priority for *policy*.");
4788
4789static PyObject *
4790posix_sched_get_priority_min(PyObject *self, PyObject *args)
4791{
4792 int policy, min;
4793
4794 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
4795 return NULL;
4796 min = sched_get_priority_min(policy);
4797 if (min < 0)
4798 return posix_error();
4799 return PyLong_FromLong(min);
4800}
4801
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02004802#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
4803
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004804#ifdef HAVE_SCHED_SETSCHEDULER
4805
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004806PyDoc_STRVAR(posix_sched_getscheduler__doc__,
4807"sched_getscheduler(pid)\n\n\
4808Get the scheduling policy for the process with a PID of *pid*.\n\
4809Passing a PID of 0 returns the scheduling policy for the calling process.");
4810
4811static PyObject *
4812posix_sched_getscheduler(PyObject *self, PyObject *args)
4813{
4814 pid_t pid;
4815 int policy;
4816
4817 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
4818 return NULL;
4819 policy = sched_getscheduler(pid);
4820 if (policy < 0)
4821 return posix_error();
4822 return PyLong_FromLong(policy);
4823}
4824
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004825#endif
4826
4827#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
4828
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004829static PyObject *
4830sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
4831{
4832 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05004833 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004834
4835 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
4836 return NULL;
4837 res = PyStructSequence_New(type);
4838 if (!res)
4839 return NULL;
4840 Py_INCREF(priority);
4841 PyStructSequence_SET_ITEM(res, 0, priority);
4842 return res;
4843}
4844
4845PyDoc_STRVAR(sched_param__doc__,
4846"sched_param(sched_priority): A scheduling parameter.\n\n\
4847Current has only one field: sched_priority");
4848
4849static PyStructSequence_Field sched_param_fields[] = {
4850 {"sched_priority", "the scheduling priority"},
4851 {0}
4852};
4853
4854static PyStructSequence_Desc sched_param_desc = {
4855 "sched_param", /* name */
4856 sched_param__doc__, /* doc */
4857 sched_param_fields,
4858 1
4859};
4860
4861static int
4862convert_sched_param(PyObject *param, struct sched_param *res)
4863{
4864 long priority;
4865
4866 if (Py_TYPE(param) != &SchedParamType) {
4867 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
4868 return 0;
4869 }
4870 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
4871 if (priority == -1 && PyErr_Occurred())
4872 return 0;
4873 if (priority > INT_MAX || priority < INT_MIN) {
4874 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
4875 return 0;
4876 }
4877 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
4878 return 1;
4879}
4880
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004881#endif
4882
4883#ifdef HAVE_SCHED_SETSCHEDULER
4884
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004885PyDoc_STRVAR(posix_sched_setscheduler__doc__,
4886"sched_setscheduler(pid, policy, param)\n\n\
4887Set the scheduling policy, *policy*, for *pid*.\n\
4888If *pid* is 0, the calling process is changed.\n\
4889*param* is an instance of sched_param.");
4890
4891static PyObject *
4892posix_sched_setscheduler(PyObject *self, PyObject *args)
4893{
4894 pid_t pid;
4895 int policy;
4896 struct sched_param param;
4897
4898 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
4899 &pid, &policy, &convert_sched_param, &param))
4900 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02004901
4902 /*
Jesus Cea54b01492011-09-10 01:53:19 +02004903 ** sched_setscheduler() returns 0 in Linux, but the previous
4904 ** scheduling policy under Solaris/Illumos, and others.
4905 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02004906 */
4907 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004908 return posix_error();
4909 Py_RETURN_NONE;
4910}
4911
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004912#endif
4913
4914#ifdef HAVE_SCHED_SETPARAM
4915
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004916PyDoc_STRVAR(posix_sched_getparam__doc__,
4917"sched_getparam(pid) -> sched_param\n\n\
4918Returns scheduling parameters for the process with *pid* as an instance of the\n\
4919sched_param class. A PID of 0 means the calling process.");
4920
4921static PyObject *
4922posix_sched_getparam(PyObject *self, PyObject *args)
4923{
4924 pid_t pid;
4925 struct sched_param param;
4926 PyObject *res, *priority;
4927
4928 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
4929 return NULL;
4930 if (sched_getparam(pid, &param))
4931 return posix_error();
4932 res = PyStructSequence_New(&SchedParamType);
4933 if (!res)
4934 return NULL;
4935 priority = PyLong_FromLong(param.sched_priority);
4936 if (!priority) {
4937 Py_DECREF(res);
4938 return NULL;
4939 }
4940 PyStructSequence_SET_ITEM(res, 0, priority);
4941 return res;
4942}
4943
4944PyDoc_STRVAR(posix_sched_setparam__doc__,
4945"sched_setparam(pid, param)\n\n\
4946Set scheduling parameters for a process with PID *pid*.\n\
4947A PID of 0 means the calling process.");
4948
4949static PyObject *
4950posix_sched_setparam(PyObject *self, PyObject *args)
4951{
4952 pid_t pid;
4953 struct sched_param param;
4954
4955 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
4956 &pid, &convert_sched_param, &param))
4957 return NULL;
4958 if (sched_setparam(pid, &param))
4959 return posix_error();
4960 Py_RETURN_NONE;
4961}
4962
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004963#endif
4964
4965#ifdef HAVE_SCHED_RR_GET_INTERVAL
4966
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004967PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
4968"sched_rr_get_interval(pid) -> float\n\n\
4969Return the round-robin quantum for the process with PID *pid* in seconds.");
4970
4971static PyObject *
4972posix_sched_rr_get_interval(PyObject *self, PyObject *args)
4973{
4974 pid_t pid;
4975 struct timespec interval;
4976
4977 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
4978 return NULL;
4979 if (sched_rr_get_interval(pid, &interval))
4980 return posix_error();
4981 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
4982}
4983
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004984#endif
4985
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004986PyDoc_STRVAR(posix_sched_yield__doc__,
4987"sched_yield()\n\n\
4988Voluntarily relinquish the CPU.");
4989
4990static PyObject *
4991posix_sched_yield(PyObject *self, PyObject *noargs)
4992{
4993 if (sched_yield())
4994 return posix_error();
4995 Py_RETURN_NONE;
4996}
4997
Benjamin Peterson2740af82011-08-02 17:41:34 -05004998#ifdef HAVE_SCHED_SETAFFINITY
4999
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005000typedef struct {
5001 PyObject_HEAD;
5002 Py_ssize_t size;
5003 int ncpus;
5004 cpu_set_t *set;
5005} Py_cpu_set;
5006
5007static PyTypeObject cpu_set_type;
5008
5009static void
5010cpu_set_dealloc(Py_cpu_set *set)
5011{
5012 assert(set->set);
5013 CPU_FREE(set->set);
5014 Py_TYPE(set)->tp_free(set);
5015}
5016
5017static Py_cpu_set *
5018make_new_cpu_set(PyTypeObject *type, Py_ssize_t size)
5019{
5020 Py_cpu_set *set;
5021
5022 if (size < 0) {
5023 PyErr_SetString(PyExc_ValueError, "negative size");
5024 return NULL;
5025 }
5026 set = (Py_cpu_set *)type->tp_alloc(type, 0);
5027 if (!set)
5028 return NULL;
5029 set->ncpus = size;
5030 set->size = CPU_ALLOC_SIZE(size);
5031 set->set = CPU_ALLOC(size);
5032 if (!set->set) {
5033 type->tp_free(set);
5034 PyErr_NoMemory();
5035 return NULL;
5036 }
5037 CPU_ZERO_S(set->size, set->set);
5038 return set;
5039}
5040
5041static PyObject *
5042cpu_set_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5043{
5044 int size;
5045
5046 if (!_PyArg_NoKeywords("cpu_set()", kwargs) ||
5047 !PyArg_ParseTuple(args, "i:cpu_set", &size))
5048 return NULL;
5049 return (PyObject *)make_new_cpu_set(type, size);
5050}
5051
5052static PyObject *
5053cpu_set_repr(Py_cpu_set *set)
5054{
5055 return PyUnicode_FromFormat("<cpu_set with %li entries>", set->ncpus);
Victor Stinner63941882011-09-29 00:42:28 +02005056}
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005057
5058static Py_ssize_t
5059cpu_set_len(Py_cpu_set *set)
5060{
5061 return set->ncpus;
5062}
5063
5064static int
5065_get_cpu(Py_cpu_set *set, const char *requester, PyObject *args)
5066{
5067 int cpu;
5068 if (!PyArg_ParseTuple(args, requester, &cpu))
5069 return -1;
5070 if (cpu < 0) {
5071 PyErr_SetString(PyExc_ValueError, "cpu < 0 not valid");
5072 return -1;
5073 }
5074 if (cpu >= set->ncpus) {
5075 PyErr_SetString(PyExc_ValueError, "cpu too large for set");
5076 return -1;
5077 }
5078 return cpu;
5079}
5080
5081PyDoc_STRVAR(cpu_set_set_doc,
5082"cpu_set.set(i)\n\n\
5083Add CPU *i* to the set.");
5084
5085static PyObject *
5086cpu_set_set(Py_cpu_set *set, PyObject *args)
5087{
5088 int cpu = _get_cpu(set, "i|set", args);
5089 if (cpu == -1)
5090 return NULL;
5091 CPU_SET_S(cpu, set->size, set->set);
5092 Py_RETURN_NONE;
5093}
5094
5095PyDoc_STRVAR(cpu_set_count_doc,
5096"cpu_set.count() -> int\n\n\
5097Return the number of CPUs active in the set.");
5098
5099static PyObject *
5100cpu_set_count(Py_cpu_set *set, PyObject *noargs)
5101{
5102 return PyLong_FromLong(CPU_COUNT_S(set->size, set->set));
5103}
5104
5105PyDoc_STRVAR(cpu_set_clear_doc,
5106"cpu_set.clear(i)\n\n\
5107Remove CPU *i* from the set.");
5108
5109static PyObject *
5110cpu_set_clear(Py_cpu_set *set, PyObject *args)
5111{
5112 int cpu = _get_cpu(set, "i|clear", args);
5113 if (cpu == -1)
5114 return NULL;
5115 CPU_CLR_S(cpu, set->size, set->set);
5116 Py_RETURN_NONE;
5117}
5118
5119PyDoc_STRVAR(cpu_set_isset_doc,
5120"cpu_set.isset(i) -> bool\n\n\
5121Test if CPU *i* is in the set.");
5122
5123static PyObject *
5124cpu_set_isset(Py_cpu_set *set, PyObject *args)
5125{
5126 int cpu = _get_cpu(set, "i|isset", args);
5127 if (cpu == -1)
5128 return NULL;
5129 if (CPU_ISSET_S(cpu, set->size, set->set))
5130 Py_RETURN_TRUE;
5131 Py_RETURN_FALSE;
5132}
5133
5134PyDoc_STRVAR(cpu_set_zero_doc,
5135"cpu_set.zero()\n\n\
5136Clear the cpu_set.");
5137
5138static PyObject *
5139cpu_set_zero(Py_cpu_set *set, PyObject *noargs)
5140{
5141 CPU_ZERO_S(set->size, set->set);
5142 Py_RETURN_NONE;
5143}
5144
5145static PyObject *
5146cpu_set_richcompare(Py_cpu_set *set, Py_cpu_set *other, int op)
5147{
5148 int eq;
5149
Brian Curtindfc80e32011-08-10 20:28:54 -05005150 if ((op != Py_EQ && op != Py_NE) || Py_TYPE(other) != &cpu_set_type)
5151 Py_RETURN_NOTIMPLEMENTED;
5152
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005153 eq = set->ncpus == other->ncpus && CPU_EQUAL_S(set->size, set->set, other->set);
5154 if ((op == Py_EQ) ? eq : !eq)
5155 Py_RETURN_TRUE;
5156 else
5157 Py_RETURN_FALSE;
5158}
5159
5160#define CPU_SET_BINOP(name, op) \
5161 static PyObject * \
5162 do_cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right, Py_cpu_set *res) { \
5163 if (res) { \
5164 Py_INCREF(res); \
5165 } \
5166 else { \
Benjamin Petersone870fe62011-08-02 17:44:26 -05005167 res = make_new_cpu_set(&cpu_set_type, left->ncpus); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005168 if (!res) \
5169 return NULL; \
5170 } \
Benjamin Peterson9b374bf2011-08-02 18:22:30 -05005171 if (Py_TYPE(right) != &cpu_set_type || left->ncpus != right->ncpus) { \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005172 Py_DECREF(res); \
Brian Curtindfc80e32011-08-10 20:28:54 -05005173 Py_RETURN_NOTIMPLEMENTED; \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005174 } \
Benjamin Peterson8f7bdd32011-08-02 18:34:30 -05005175 assert(left->size == right->size && right->size == res->size); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005176 op(res->size, res->set, left->set, right->set); \
5177 return (PyObject *)res; \
5178 } \
5179 static PyObject * \
5180 cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right) { \
5181 return do_cpu_set_##name(left, right, NULL); \
5182 } \
5183 static PyObject * \
5184 cpu_set_i##name(Py_cpu_set *left, Py_cpu_set *right) { \
5185 return do_cpu_set_##name(left, right, left); \
5186 } \
5187
5188CPU_SET_BINOP(and, CPU_AND_S)
5189CPU_SET_BINOP(or, CPU_OR_S)
5190CPU_SET_BINOP(xor, CPU_XOR_S)
5191#undef CPU_SET_BINOP
5192
5193PyDoc_STRVAR(cpu_set_doc,
5194"cpu_set(size)\n\n\
5195Create an empty mask of CPUs.");
5196
5197static PyNumberMethods cpu_set_as_number = {
5198 0, /*nb_add*/
5199 0, /*nb_subtract*/
5200 0, /*nb_multiply*/
5201 0, /*nb_remainder*/
5202 0, /*nb_divmod*/
5203 0, /*nb_power*/
5204 0, /*nb_negative*/
5205 0, /*nb_positive*/
5206 0, /*nb_absolute*/
5207 0, /*nb_bool*/
5208 0, /*nb_invert*/
5209 0, /*nb_lshift*/
5210 0, /*nb_rshift*/
5211 (binaryfunc)cpu_set_and, /*nb_and*/
5212 (binaryfunc)cpu_set_xor, /*nb_xor*/
5213 (binaryfunc)cpu_set_or, /*nb_or*/
5214 0, /*nb_int*/
5215 0, /*nb_reserved*/
5216 0, /*nb_float*/
5217 0, /*nb_inplace_add*/
5218 0, /*nb_inplace_subtract*/
5219 0, /*nb_inplace_multiply*/
5220 0, /*nb_inplace_remainder*/
5221 0, /*nb_inplace_power*/
5222 0, /*nb_inplace_lshift*/
5223 0, /*nb_inplace_rshift*/
5224 (binaryfunc)cpu_set_iand, /*nb_inplace_and*/
5225 (binaryfunc)cpu_set_ixor, /*nb_inplace_xor*/
5226 (binaryfunc)cpu_set_ior, /*nb_inplace_or*/
5227};
5228
5229static PySequenceMethods cpu_set_as_sequence = {
5230 (lenfunc)cpu_set_len, /* sq_length */
5231};
5232
5233static PyMethodDef cpu_set_methods[] = {
5234 {"clear", (PyCFunction)cpu_set_clear, METH_VARARGS, cpu_set_clear_doc},
5235 {"count", (PyCFunction)cpu_set_count, METH_NOARGS, cpu_set_count_doc},
5236 {"isset", (PyCFunction)cpu_set_isset, METH_VARARGS, cpu_set_isset_doc},
5237 {"set", (PyCFunction)cpu_set_set, METH_VARARGS, cpu_set_set_doc},
5238 {"zero", (PyCFunction)cpu_set_zero, METH_NOARGS, cpu_set_zero_doc},
5239 {NULL, NULL} /* sentinel */
5240};
5241
5242static PyTypeObject cpu_set_type = {
5243 PyVarObject_HEAD_INIT(&PyType_Type, 0)
5244 "posix.cpu_set", /* tp_name */
5245 sizeof(Py_cpu_set), /* tp_basicsize */
5246 0, /* tp_itemsize */
5247 /* methods */
5248 (destructor)cpu_set_dealloc, /* tp_dealloc */
5249 0, /* tp_print */
5250 0, /* tp_getattr */
5251 0, /* tp_setattr */
5252 0, /* tp_reserved */
5253 (reprfunc)cpu_set_repr, /* tp_repr */
5254 &cpu_set_as_number, /* tp_as_number */
5255 &cpu_set_as_sequence, /* tp_as_sequence */
5256 0, /* tp_as_mapping */
5257 PyObject_HashNotImplemented, /* tp_hash */
5258 0, /* tp_call */
5259 0, /* tp_str */
5260 PyObject_GenericGetAttr, /* tp_getattro */
5261 0, /* tp_setattro */
5262 0, /* tp_as_buffer */
5263 Py_TPFLAGS_DEFAULT, /* tp_flags */
5264 cpu_set_doc, /* tp_doc */
5265 0, /* tp_traverse */
5266 0, /* tp_clear */
5267 (richcmpfunc)cpu_set_richcompare, /* tp_richcompare */
5268 0, /* tp_weaklistoffset */
5269 0, /* tp_iter */
5270 0, /* tp_iternext */
5271 cpu_set_methods, /* tp_methods */
5272 0, /* tp_members */
5273 0, /* tp_getset */
5274 0, /* tp_base */
5275 0, /* tp_dict */
5276 0, /* tp_descr_get */
5277 0, /* tp_descr_set */
5278 0, /* tp_dictoffset */
5279 0, /* tp_init */
5280 PyType_GenericAlloc, /* tp_alloc */
5281 cpu_set_new, /* tp_new */
5282 PyObject_Del, /* tp_free */
5283};
5284
5285PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5286"sched_setaffinity(pid, cpu_set)\n\n\
5287Set the affinity of the process with PID *pid* to *cpu_set*.");
5288
5289static PyObject *
5290posix_sched_setaffinity(PyObject *self, PyObject *args)
5291{
5292 pid_t pid;
5293 Py_cpu_set *cpu_set;
5294
Benjamin Petersona17a5d62011-08-09 16:49:13 -05005295 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O!:sched_setaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005296 &pid, &cpu_set_type, &cpu_set))
5297 return NULL;
5298 if (sched_setaffinity(pid, cpu_set->size, cpu_set->set))
5299 return posix_error();
5300 Py_RETURN_NONE;
5301}
5302
5303PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5304"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5305Return the affinity of the process with PID *pid*.\n\
5306The returned cpu_set will be of size *ncpus*.");
5307
5308static PyObject *
5309posix_sched_getaffinity(PyObject *self, PyObject *args)
5310{
5311 pid_t pid;
5312 int ncpus;
5313 Py_cpu_set *res;
5314
Benjamin Peterson7ac92142011-08-03 08:54:26 -05005315 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:sched_getaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005316 &pid, &ncpus))
5317 return NULL;
5318 res = make_new_cpu_set(&cpu_set_type, ncpus);
5319 if (!res)
5320 return NULL;
5321 if (sched_getaffinity(pid, res->size, res->set)) {
5322 Py_DECREF(res);
5323 return posix_error();
5324 }
5325 return (PyObject *)res;
5326}
5327
Benjamin Peterson2740af82011-08-02 17:41:34 -05005328#endif /* HAVE_SCHED_SETAFFINITY */
5329
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005330#endif /* HAVE_SCHED_H */
5331
Neal Norwitzb59798b2003-03-21 01:43:31 +00005332/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005333/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5334#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005335#define DEV_PTY_FILE "/dev/ptc"
5336#define HAVE_DEV_PTMX
5337#else
5338#define DEV_PTY_FILE "/dev/ptmx"
5339#endif
5340
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005341#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005342#ifdef HAVE_PTY_H
5343#include <pty.h>
5344#else
5345#ifdef HAVE_LIBUTIL_H
5346#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005347#else
5348#ifdef HAVE_UTIL_H
5349#include <util.h>
5350#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005351#endif /* HAVE_LIBUTIL_H */
5352#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005353#ifdef HAVE_STROPTS_H
5354#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005355#endif
5356#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005357
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005358#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005359PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005360"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005361Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005362
5363static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005364posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005365{
Victor Stinner8c62be82010-05-06 00:08:46 +00005366 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005367#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005368 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005369#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005370#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005371 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005372#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005373 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005374#endif
5375#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005376
Thomas Wouters70c21a12000-07-14 14:28:33 +00005377#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005378 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
5379 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005380#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005381 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5382 if (slave_name == NULL)
5383 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00005384
Victor Stinner8c62be82010-05-06 00:08:46 +00005385 slave_fd = open(slave_name, O_RDWR);
5386 if (slave_fd < 0)
5387 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005388#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005389 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
5390 if (master_fd < 0)
5391 return posix_error();
5392 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
5393 /* change permission of slave */
5394 if (grantpt(master_fd) < 0) {
5395 PyOS_setsig(SIGCHLD, sig_saved);
5396 return posix_error();
5397 }
5398 /* unlock slave */
5399 if (unlockpt(master_fd) < 0) {
5400 PyOS_setsig(SIGCHLD, sig_saved);
5401 return posix_error();
5402 }
5403 PyOS_setsig(SIGCHLD, sig_saved);
5404 slave_name = ptsname(master_fd); /* get name of slave */
5405 if (slave_name == NULL)
5406 return posix_error();
5407 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
5408 if (slave_fd < 0)
5409 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005410#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005411 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5412 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005413#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005414 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005415#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005416#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005417#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005418
Victor Stinner8c62be82010-05-06 00:08:46 +00005419 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005420
Fred Drake8cef4cf2000-06-28 16:40:38 +00005421}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005422#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005423
5424#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005425PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005426"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00005427Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
5428Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005429To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005430
5431static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005432posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005433{
Victor Stinner8c62be82010-05-06 00:08:46 +00005434 int master_fd = -1, result = 0;
5435 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005436
Victor Stinner8c62be82010-05-06 00:08:46 +00005437 _PyImport_AcquireLock();
5438 pid = forkpty(&master_fd, NULL, NULL, NULL);
5439 if (pid == 0) {
5440 /* child: this clobbers and resets the import lock. */
5441 PyOS_AfterFork();
5442 } else {
5443 /* parent: release the import lock. */
5444 result = _PyImport_ReleaseLock();
5445 }
5446 if (pid == -1)
5447 return posix_error();
5448 if (result < 0) {
5449 /* Don't clobber the OSError if the fork failed. */
5450 PyErr_SetString(PyExc_RuntimeError,
5451 "not holding the import lock");
5452 return NULL;
5453 }
5454 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005455}
5456#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005457
Ross Lagerwall7807c352011-03-17 20:20:30 +02005458
Guido van Rossumad0ee831995-03-01 10:34:45 +00005459#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005460PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005461"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005462Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005463
Barry Warsaw53699e91996-12-10 23:23:01 +00005464static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005465posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005466{
Victor Stinner8c62be82010-05-06 00:08:46 +00005467 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005468}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005469#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005470
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005471
Guido van Rossumad0ee831995-03-01 10:34:45 +00005472#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005473PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005474"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005475Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005476
Barry Warsaw53699e91996-12-10 23:23:01 +00005477static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005478posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005479{
Victor Stinner8c62be82010-05-06 00:08:46 +00005480 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005481}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005482#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005483
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005484
Guido van Rossumad0ee831995-03-01 10:34:45 +00005485#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005486PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005487"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005488Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005489
Barry Warsaw53699e91996-12-10 23:23:01 +00005490static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005491posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005492{
Victor Stinner8c62be82010-05-06 00:08:46 +00005493 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005494}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005495#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005496
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005497
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005498PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005499"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005500Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005501
Barry Warsaw53699e91996-12-10 23:23:01 +00005502static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005503posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005504{
Victor Stinner8c62be82010-05-06 00:08:46 +00005505 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005506}
5507
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005508#ifdef HAVE_GETGROUPLIST
5509PyDoc_STRVAR(posix_getgrouplist__doc__,
5510"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5511Returns a list of groups to which a user belongs.\n\n\
5512 user: username to lookup\n\
5513 group: base group id of the user");
5514
5515static PyObject *
5516posix_getgrouplist(PyObject *self, PyObject *args)
5517{
5518#ifdef NGROUPS_MAX
5519#define MAX_GROUPS NGROUPS_MAX
5520#else
5521 /* defined to be 16 on Solaris7, so this should be a small number */
5522#define MAX_GROUPS 64
5523#endif
5524
5525 const char *user;
5526 int i, ngroups;
5527 PyObject *list;
5528#ifdef __APPLE__
5529 int *groups, basegid;
5530#else
5531 gid_t *groups, basegid;
5532#endif
5533 ngroups = MAX_GROUPS;
5534
5535 if (!PyArg_ParseTuple(args, "si", &user, &basegid))
5536 return NULL;
5537
5538#ifdef __APPLE__
5539 groups = PyMem_Malloc(ngroups * sizeof(int));
5540#else
5541 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
5542#endif
5543 if (groups == NULL)
5544 return PyErr_NoMemory();
5545
5546 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
5547 PyMem_Del(groups);
5548 return posix_error();
5549 }
5550
5551 list = PyList_New(ngroups);
5552 if (list == NULL) {
5553 PyMem_Del(groups);
5554 return NULL;
5555 }
5556
5557 for (i = 0; i < ngroups; i++) {
5558 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
5559 if (o == NULL) {
5560 Py_DECREF(list);
5561 PyMem_Del(groups);
5562 return NULL;
5563 }
5564 PyList_SET_ITEM(list, i, o);
5565 }
5566
5567 PyMem_Del(groups);
5568
5569 return list;
5570}
5571#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005572
Fred Drakec9680921999-12-13 16:37:25 +00005573#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005574PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005575"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005576Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00005577
5578static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005579posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00005580{
5581 PyObject *result = NULL;
5582
Fred Drakec9680921999-12-13 16:37:25 +00005583#ifdef NGROUPS_MAX
5584#define MAX_GROUPS NGROUPS_MAX
5585#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005586 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00005587#define MAX_GROUPS 64
5588#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005589 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005590
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005591 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005592 * This is a helper variable to store the intermediate result when
5593 * that happens.
5594 *
5595 * To keep the code readable the OSX behaviour is unconditional,
5596 * according to the POSIX spec this should be safe on all unix-y
5597 * systems.
5598 */
5599 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005600 int n;
Fred Drakec9680921999-12-13 16:37:25 +00005601
Victor Stinner8c62be82010-05-06 00:08:46 +00005602 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005603 if (n < 0) {
5604 if (errno == EINVAL) {
5605 n = getgroups(0, NULL);
5606 if (n == -1) {
5607 return posix_error();
5608 }
5609 if (n == 0) {
5610 /* Avoid malloc(0) */
5611 alt_grouplist = grouplist;
5612 } else {
5613 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
5614 if (alt_grouplist == NULL) {
5615 errno = EINVAL;
5616 return posix_error();
5617 }
5618 n = getgroups(n, alt_grouplist);
5619 if (n == -1) {
5620 PyMem_Free(alt_grouplist);
5621 return posix_error();
5622 }
5623 }
5624 } else {
5625 return posix_error();
5626 }
5627 }
5628 result = PyList_New(n);
5629 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005630 int i;
5631 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005632 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00005633 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00005634 Py_DECREF(result);
5635 result = NULL;
5636 break;
Fred Drakec9680921999-12-13 16:37:25 +00005637 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005638 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00005639 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005640 }
5641
5642 if (alt_grouplist != grouplist) {
5643 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005644 }
Neal Norwitze241ce82003-02-17 18:17:05 +00005645
Fred Drakec9680921999-12-13 16:37:25 +00005646 return result;
5647}
5648#endif
5649
Antoine Pitroub7572f02009-12-02 20:46:48 +00005650#ifdef HAVE_INITGROUPS
5651PyDoc_STRVAR(posix_initgroups__doc__,
5652"initgroups(username, gid) -> None\n\n\
5653Call the system initgroups() to initialize the group access list with all of\n\
5654the groups of which the specified username is a member, plus the specified\n\
5655group id.");
5656
5657static PyObject *
5658posix_initgroups(PyObject *self, PyObject *args)
5659{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005660 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00005661 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005662 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00005663 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005664
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005665 if (!PyArg_ParseTuple(args, "O&l:initgroups",
5666 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00005667 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005668 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005669
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005670 res = initgroups(username, (gid_t) gid);
5671 Py_DECREF(oname);
5672 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00005673 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005674
Victor Stinner8c62be82010-05-06 00:08:46 +00005675 Py_INCREF(Py_None);
5676 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005677}
5678#endif
5679
Martin v. Löwis606edc12002-06-13 21:09:11 +00005680#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005681PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005682"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005683Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00005684
5685static PyObject *
5686posix_getpgid(PyObject *self, PyObject *args)
5687{
Victor Stinner8c62be82010-05-06 00:08:46 +00005688 pid_t pid, pgid;
5689 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
5690 return NULL;
5691 pgid = getpgid(pid);
5692 if (pgid < 0)
5693 return posix_error();
5694 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00005695}
5696#endif /* HAVE_GETPGID */
5697
5698
Guido van Rossumb6775db1994-08-01 11:34:53 +00005699#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005700PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005701"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005702Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005703
Barry Warsaw53699e91996-12-10 23:23:01 +00005704static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005705posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00005706{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005707#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005708 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005709#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005710 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005711#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00005712}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005713#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00005714
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005715
Guido van Rossumb6775db1994-08-01 11:34:53 +00005716#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005717PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005718"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00005719Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005720
Barry Warsaw53699e91996-12-10 23:23:01 +00005721static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005722posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005723{
Guido van Rossum64933891994-10-20 21:56:42 +00005724#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005725 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005726#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005727 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005728#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005729 return posix_error();
5730 Py_INCREF(Py_None);
5731 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005732}
5733
Guido van Rossumb6775db1994-08-01 11:34:53 +00005734#endif /* HAVE_SETPGRP */
5735
Guido van Rossumad0ee831995-03-01 10:34:45 +00005736#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005737
5738#ifdef MS_WINDOWS
5739#include <tlhelp32.h>
5740
5741static PyObject*
5742win32_getppid()
5743{
5744 HANDLE snapshot;
5745 pid_t mypid;
5746 PyObject* result = NULL;
5747 BOOL have_record;
5748 PROCESSENTRY32 pe;
5749
5750 mypid = getpid(); /* This function never fails */
5751
5752 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
5753 if (snapshot == INVALID_HANDLE_VALUE)
5754 return PyErr_SetFromWindowsErr(GetLastError());
5755
5756 pe.dwSize = sizeof(pe);
5757 have_record = Process32First(snapshot, &pe);
5758 while (have_record) {
5759 if (mypid == (pid_t)pe.th32ProcessID) {
5760 /* We could cache the ulong value in a static variable. */
5761 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
5762 break;
5763 }
5764
5765 have_record = Process32Next(snapshot, &pe);
5766 }
5767
5768 /* If our loop exits and our pid was not found (result will be NULL)
5769 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
5770 * error anyway, so let's raise it. */
5771 if (!result)
5772 result = PyErr_SetFromWindowsErr(GetLastError());
5773
5774 CloseHandle(snapshot);
5775
5776 return result;
5777}
5778#endif /*MS_WINDOWS*/
5779
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005780PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005781"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005782Return the parent's process id. If the parent process has already exited,\n\
5783Windows machines will still return its id; others systems will return the id\n\
5784of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005785
Barry Warsaw53699e91996-12-10 23:23:01 +00005786static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005787posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005788{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005789#ifdef MS_WINDOWS
5790 return win32_getppid();
5791#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005792 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00005793#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005794}
5795#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005796
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005797
Fred Drake12c6e2d1999-12-14 21:25:03 +00005798#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005799PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005800"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005801Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00005802
5803static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005804posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005805{
Victor Stinner8c62be82010-05-06 00:08:46 +00005806 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005807#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005808 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02005809 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005810
5811 if (GetUserNameW(user_name, &num_chars)) {
5812 /* num_chars is the number of unicode chars plus null terminator */
5813 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005814 }
5815 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005816 result = PyErr_SetFromWindowsErr(GetLastError());
5817#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005818 char *name;
5819 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005820
Victor Stinner8c62be82010-05-06 00:08:46 +00005821 errno = 0;
5822 name = getlogin();
5823 if (name == NULL) {
5824 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00005825 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00005826 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00005827 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00005828 }
5829 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00005830 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00005831 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005832#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00005833 return result;
5834}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005835#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005836
Guido van Rossumad0ee831995-03-01 10:34:45 +00005837#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005838PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005839"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005840Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005841
Barry Warsaw53699e91996-12-10 23:23:01 +00005842static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005843posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005844{
Victor Stinner8c62be82010-05-06 00:08:46 +00005845 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005846}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005847#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005848
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005849
Guido van Rossumad0ee831995-03-01 10:34:45 +00005850#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005851PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005852"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005853Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005854
Barry Warsaw53699e91996-12-10 23:23:01 +00005855static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005856posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005857{
Victor Stinner8c62be82010-05-06 00:08:46 +00005858 pid_t pid;
5859 int sig;
5860 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
5861 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005862#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005863 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
5864 APIRET rc;
5865 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005866 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005867
5868 } else if (sig == XCPT_SIGNAL_KILLPROC) {
5869 APIRET rc;
5870 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005871 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005872
5873 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00005874 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005875#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005876 if (kill(pid, sig) == -1)
5877 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005878#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005879 Py_INCREF(Py_None);
5880 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00005881}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005882#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005883
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005884#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005885PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005886"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005887Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005888
5889static PyObject *
5890posix_killpg(PyObject *self, PyObject *args)
5891{
Victor Stinner8c62be82010-05-06 00:08:46 +00005892 int sig;
5893 pid_t pgid;
5894 /* XXX some man pages make the `pgid` parameter an int, others
5895 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
5896 take the same type. Moreover, pid_t is always at least as wide as
5897 int (else compilation of this module fails), which is safe. */
5898 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
5899 return NULL;
5900 if (killpg(pgid, sig) == -1)
5901 return posix_error();
5902 Py_INCREF(Py_None);
5903 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005904}
5905#endif
5906
Brian Curtineb24d742010-04-12 17:16:38 +00005907#ifdef MS_WINDOWS
5908PyDoc_STRVAR(win32_kill__doc__,
5909"kill(pid, sig)\n\n\
5910Kill a process with a signal.");
5911
5912static PyObject *
5913win32_kill(PyObject *self, PyObject *args)
5914{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00005915 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00005916 DWORD pid, sig, err;
5917 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00005918
Victor Stinner8c62be82010-05-06 00:08:46 +00005919 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
5920 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00005921
Victor Stinner8c62be82010-05-06 00:08:46 +00005922 /* Console processes which share a common console can be sent CTRL+C or
5923 CTRL+BREAK events, provided they handle said events. */
5924 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
5925 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
5926 err = GetLastError();
5927 PyErr_SetFromWindowsErr(err);
5928 }
5929 else
5930 Py_RETURN_NONE;
5931 }
Brian Curtineb24d742010-04-12 17:16:38 +00005932
Victor Stinner8c62be82010-05-06 00:08:46 +00005933 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
5934 attempt to open and terminate the process. */
5935 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
5936 if (handle == NULL) {
5937 err = GetLastError();
5938 return PyErr_SetFromWindowsErr(err);
5939 }
Brian Curtineb24d742010-04-12 17:16:38 +00005940
Victor Stinner8c62be82010-05-06 00:08:46 +00005941 if (TerminateProcess(handle, sig) == 0) {
5942 err = GetLastError();
5943 result = PyErr_SetFromWindowsErr(err);
5944 } else {
5945 Py_INCREF(Py_None);
5946 result = Py_None;
5947 }
Brian Curtineb24d742010-04-12 17:16:38 +00005948
Victor Stinner8c62be82010-05-06 00:08:46 +00005949 CloseHandle(handle);
5950 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00005951}
5952#endif /* MS_WINDOWS */
5953
Guido van Rossumc0125471996-06-28 18:55:32 +00005954#ifdef HAVE_PLOCK
5955
5956#ifdef HAVE_SYS_LOCK_H
5957#include <sys/lock.h>
5958#endif
5959
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005960PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005961"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005962Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005963
Barry Warsaw53699e91996-12-10 23:23:01 +00005964static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005965posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00005966{
Victor Stinner8c62be82010-05-06 00:08:46 +00005967 int op;
5968 if (!PyArg_ParseTuple(args, "i:plock", &op))
5969 return NULL;
5970 if (plock(op) == -1)
5971 return posix_error();
5972 Py_INCREF(Py_None);
5973 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00005974}
5975#endif
5976
Guido van Rossumb6775db1994-08-01 11:34:53 +00005977#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005978PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005979"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005980Set the current process's user id.");
5981
Barry Warsaw53699e91996-12-10 23:23:01 +00005982static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005983posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005984{
Victor Stinner8c62be82010-05-06 00:08:46 +00005985 long uid_arg;
5986 uid_t uid;
5987 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
5988 return NULL;
5989 uid = uid_arg;
5990 if (uid != uid_arg) {
5991 PyErr_SetString(PyExc_OverflowError, "user id too big");
5992 return NULL;
5993 }
5994 if (setuid(uid) < 0)
5995 return posix_error();
5996 Py_INCREF(Py_None);
5997 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005998}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005999#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006000
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006001
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006002#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006003PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006004"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006005Set the current process's effective user id.");
6006
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006007static PyObject *
6008posix_seteuid (PyObject *self, PyObject *args)
6009{
Victor Stinner8c62be82010-05-06 00:08:46 +00006010 long euid_arg;
6011 uid_t euid;
6012 if (!PyArg_ParseTuple(args, "l", &euid_arg))
6013 return NULL;
6014 euid = euid_arg;
6015 if (euid != euid_arg) {
6016 PyErr_SetString(PyExc_OverflowError, "user id too big");
6017 return NULL;
6018 }
6019 if (seteuid(euid) < 0) {
6020 return posix_error();
6021 } else {
6022 Py_INCREF(Py_None);
6023 return Py_None;
6024 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006025}
6026#endif /* HAVE_SETEUID */
6027
6028#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006029PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006030"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006031Set the current process's effective group id.");
6032
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006033static PyObject *
6034posix_setegid (PyObject *self, PyObject *args)
6035{
Victor Stinner8c62be82010-05-06 00:08:46 +00006036 long egid_arg;
6037 gid_t egid;
6038 if (!PyArg_ParseTuple(args, "l", &egid_arg))
6039 return NULL;
6040 egid = egid_arg;
6041 if (egid != egid_arg) {
6042 PyErr_SetString(PyExc_OverflowError, "group id too big");
6043 return NULL;
6044 }
6045 if (setegid(egid) < 0) {
6046 return posix_error();
6047 } else {
6048 Py_INCREF(Py_None);
6049 return Py_None;
6050 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006051}
6052#endif /* HAVE_SETEGID */
6053
6054#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006055PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006056"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006057Set the current process's real and effective user ids.");
6058
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006059static PyObject *
6060posix_setreuid (PyObject *self, PyObject *args)
6061{
Victor Stinner8c62be82010-05-06 00:08:46 +00006062 long ruid_arg, euid_arg;
6063 uid_t ruid, euid;
6064 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
6065 return NULL;
6066 if (ruid_arg == -1)
6067 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
6068 else
6069 ruid = ruid_arg; /* otherwise, assign from our long */
6070 if (euid_arg == -1)
6071 euid = (uid_t)-1;
6072 else
6073 euid = euid_arg;
6074 if ((euid_arg != -1 && euid != euid_arg) ||
6075 (ruid_arg != -1 && ruid != ruid_arg)) {
6076 PyErr_SetString(PyExc_OverflowError, "user id too big");
6077 return NULL;
6078 }
6079 if (setreuid(ruid, euid) < 0) {
6080 return posix_error();
6081 } else {
6082 Py_INCREF(Py_None);
6083 return Py_None;
6084 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006085}
6086#endif /* HAVE_SETREUID */
6087
6088#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006089PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006090"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006091Set the current process's real and effective group ids.");
6092
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006093static PyObject *
6094posix_setregid (PyObject *self, PyObject *args)
6095{
Victor Stinner8c62be82010-05-06 00:08:46 +00006096 long rgid_arg, egid_arg;
6097 gid_t rgid, egid;
6098 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
6099 return NULL;
6100 if (rgid_arg == -1)
6101 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
6102 else
6103 rgid = rgid_arg; /* otherwise, assign from our long */
6104 if (egid_arg == -1)
6105 egid = (gid_t)-1;
6106 else
6107 egid = egid_arg;
6108 if ((egid_arg != -1 && egid != egid_arg) ||
6109 (rgid_arg != -1 && rgid != rgid_arg)) {
6110 PyErr_SetString(PyExc_OverflowError, "group id too big");
6111 return NULL;
6112 }
6113 if (setregid(rgid, egid) < 0) {
6114 return posix_error();
6115 } else {
6116 Py_INCREF(Py_None);
6117 return Py_None;
6118 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006119}
6120#endif /* HAVE_SETREGID */
6121
Guido van Rossumb6775db1994-08-01 11:34:53 +00006122#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006123PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006124"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006125Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006126
Barry Warsaw53699e91996-12-10 23:23:01 +00006127static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006128posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006129{
Victor Stinner8c62be82010-05-06 00:08:46 +00006130 long gid_arg;
6131 gid_t gid;
6132 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
6133 return NULL;
6134 gid = gid_arg;
6135 if (gid != gid_arg) {
6136 PyErr_SetString(PyExc_OverflowError, "group id too big");
6137 return NULL;
6138 }
6139 if (setgid(gid) < 0)
6140 return posix_error();
6141 Py_INCREF(Py_None);
6142 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006143}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006144#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006145
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006146#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006147PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006148"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006149Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006150
6151static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006152posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006153{
Victor Stinner8c62be82010-05-06 00:08:46 +00006154 int i, len;
6155 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006156
Victor Stinner8c62be82010-05-06 00:08:46 +00006157 if (!PySequence_Check(groups)) {
6158 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6159 return NULL;
6160 }
6161 len = PySequence_Size(groups);
6162 if (len > MAX_GROUPS) {
6163 PyErr_SetString(PyExc_ValueError, "too many groups");
6164 return NULL;
6165 }
6166 for(i = 0; i < len; i++) {
6167 PyObject *elem;
6168 elem = PySequence_GetItem(groups, i);
6169 if (!elem)
6170 return NULL;
6171 if (!PyLong_Check(elem)) {
6172 PyErr_SetString(PyExc_TypeError,
6173 "groups must be integers");
6174 Py_DECREF(elem);
6175 return NULL;
6176 } else {
6177 unsigned long x = PyLong_AsUnsignedLong(elem);
6178 if (PyErr_Occurred()) {
6179 PyErr_SetString(PyExc_TypeError,
6180 "group id too big");
6181 Py_DECREF(elem);
6182 return NULL;
6183 }
6184 grouplist[i] = x;
6185 /* read back the value to see if it fitted in gid_t */
6186 if (grouplist[i] != x) {
6187 PyErr_SetString(PyExc_TypeError,
6188 "group id too big");
6189 Py_DECREF(elem);
6190 return NULL;
6191 }
6192 }
6193 Py_DECREF(elem);
6194 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006195
Victor Stinner8c62be82010-05-06 00:08:46 +00006196 if (setgroups(len, grouplist) < 0)
6197 return posix_error();
6198 Py_INCREF(Py_None);
6199 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006200}
6201#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006202
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006203#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6204static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006205wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006206{
Victor Stinner8c62be82010-05-06 00:08:46 +00006207 PyObject *result;
6208 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006209 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006210
Victor Stinner8c62be82010-05-06 00:08:46 +00006211 if (pid == -1)
6212 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006213
Victor Stinner8c62be82010-05-06 00:08:46 +00006214 if (struct_rusage == NULL) {
6215 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6216 if (m == NULL)
6217 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006218 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006219 Py_DECREF(m);
6220 if (struct_rusage == NULL)
6221 return NULL;
6222 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006223
Victor Stinner8c62be82010-05-06 00:08:46 +00006224 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6225 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6226 if (!result)
6227 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006228
6229#ifndef doubletime
6230#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6231#endif
6232
Victor Stinner8c62be82010-05-06 00:08:46 +00006233 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006234 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006235 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006236 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006237#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006238 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6239 SET_INT(result, 2, ru->ru_maxrss);
6240 SET_INT(result, 3, ru->ru_ixrss);
6241 SET_INT(result, 4, ru->ru_idrss);
6242 SET_INT(result, 5, ru->ru_isrss);
6243 SET_INT(result, 6, ru->ru_minflt);
6244 SET_INT(result, 7, ru->ru_majflt);
6245 SET_INT(result, 8, ru->ru_nswap);
6246 SET_INT(result, 9, ru->ru_inblock);
6247 SET_INT(result, 10, ru->ru_oublock);
6248 SET_INT(result, 11, ru->ru_msgsnd);
6249 SET_INT(result, 12, ru->ru_msgrcv);
6250 SET_INT(result, 13, ru->ru_nsignals);
6251 SET_INT(result, 14, ru->ru_nvcsw);
6252 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006253#undef SET_INT
6254
Victor Stinner8c62be82010-05-06 00:08:46 +00006255 if (PyErr_Occurred()) {
6256 Py_DECREF(result);
6257 return NULL;
6258 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006259
Victor Stinner8c62be82010-05-06 00:08:46 +00006260 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006261}
6262#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6263
6264#ifdef HAVE_WAIT3
6265PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006266"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006267Wait for completion of a child process.");
6268
6269static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006270posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006271{
Victor Stinner8c62be82010-05-06 00:08:46 +00006272 pid_t pid;
6273 int options;
6274 struct rusage ru;
6275 WAIT_TYPE status;
6276 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006277
Victor Stinner4195b5c2012-02-08 23:03:19 +01006278 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006279 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006280
Victor Stinner8c62be82010-05-06 00:08:46 +00006281 Py_BEGIN_ALLOW_THREADS
6282 pid = wait3(&status, options, &ru);
6283 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006284
Victor Stinner4195b5c2012-02-08 23:03:19 +01006285 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006286}
6287#endif /* HAVE_WAIT3 */
6288
6289#ifdef HAVE_WAIT4
6290PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006291"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006292Wait for completion of a given child process.");
6293
6294static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006295posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006296{
Victor Stinner8c62be82010-05-06 00:08:46 +00006297 pid_t pid;
6298 int options;
6299 struct rusage ru;
6300 WAIT_TYPE status;
6301 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006302
Victor Stinner4195b5c2012-02-08 23:03:19 +01006303 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006304 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006305
Victor Stinner8c62be82010-05-06 00:08:46 +00006306 Py_BEGIN_ALLOW_THREADS
6307 pid = wait4(pid, &status, options, &ru);
6308 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006309
Victor Stinner4195b5c2012-02-08 23:03:19 +01006310 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006311}
6312#endif /* HAVE_WAIT4 */
6313
Ross Lagerwall7807c352011-03-17 20:20:30 +02006314#if defined(HAVE_WAITID) && !defined(__APPLE__)
6315PyDoc_STRVAR(posix_waitid__doc__,
6316"waitid(idtype, id, options) -> waitid_result\n\n\
6317Wait for the completion of one or more child processes.\n\n\
6318idtype can be P_PID, P_PGID or P_ALL.\n\
6319id specifies the pid to wait on.\n\
6320options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6321or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6322Returns either waitid_result or None if WNOHANG is specified and there are\n\
6323no children in a waitable state.");
6324
6325static PyObject *
6326posix_waitid(PyObject *self, PyObject *args)
6327{
6328 PyObject *result;
6329 idtype_t idtype;
6330 id_t id;
6331 int options, res;
6332 siginfo_t si;
6333 si.si_pid = 0;
6334 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6335 return NULL;
6336 Py_BEGIN_ALLOW_THREADS
6337 res = waitid(idtype, id, &si, options);
6338 Py_END_ALLOW_THREADS
6339 if (res == -1)
6340 return posix_error();
6341
6342 if (si.si_pid == 0)
6343 Py_RETURN_NONE;
6344
6345 result = PyStructSequence_New(&WaitidResultType);
6346 if (!result)
6347 return NULL;
6348
6349 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
6350 PyStructSequence_SET_ITEM(result, 1, PyLong_FromPid(si.si_uid));
6351 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6352 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6353 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6354 if (PyErr_Occurred()) {
6355 Py_DECREF(result);
6356 return NULL;
6357 }
6358
6359 return result;
6360}
6361#endif
6362
Guido van Rossumb6775db1994-08-01 11:34:53 +00006363#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006364PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006365"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006366Wait for completion of a given child process.");
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_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006370{
Victor Stinner8c62be82010-05-06 00:08:46 +00006371 pid_t pid;
6372 int options;
6373 WAIT_TYPE status;
6374 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006375
Victor Stinner8c62be82010-05-06 00:08:46 +00006376 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6377 return NULL;
6378 Py_BEGIN_ALLOW_THREADS
6379 pid = waitpid(pid, &status, options);
6380 Py_END_ALLOW_THREADS
6381 if (pid == -1)
6382 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006383
Victor Stinner8c62be82010-05-06 00:08:46 +00006384 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006385}
6386
Tim Petersab034fa2002-02-01 11:27:43 +00006387#elif defined(HAVE_CWAIT)
6388
6389/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006390PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006391"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006392"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006393
6394static PyObject *
6395posix_waitpid(PyObject *self, PyObject *args)
6396{
Victor Stinner8c62be82010-05-06 00:08:46 +00006397 Py_intptr_t pid;
6398 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006399
Victor Stinner8c62be82010-05-06 00:08:46 +00006400 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6401 return NULL;
6402 Py_BEGIN_ALLOW_THREADS
6403 pid = _cwait(&status, pid, options);
6404 Py_END_ALLOW_THREADS
6405 if (pid == -1)
6406 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006407
Victor Stinner8c62be82010-05-06 00:08:46 +00006408 /* shift the status left a byte so this is more like the POSIX waitpid */
6409 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006410}
6411#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006412
Guido van Rossumad0ee831995-03-01 10:34:45 +00006413#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006414PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006415"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006416Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006417
Barry Warsaw53699e91996-12-10 23:23:01 +00006418static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006419posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006420{
Victor Stinner8c62be82010-05-06 00:08:46 +00006421 pid_t pid;
6422 WAIT_TYPE status;
6423 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006424
Victor Stinner8c62be82010-05-06 00:08:46 +00006425 Py_BEGIN_ALLOW_THREADS
6426 pid = wait(&status);
6427 Py_END_ALLOW_THREADS
6428 if (pid == -1)
6429 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006430
Victor Stinner8c62be82010-05-06 00:08:46 +00006431 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006432}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006433#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006434
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006435
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006436PyDoc_STRVAR(posix_lstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006437"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006438Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006439
Barry Warsaw53699e91996-12-10 23:23:01 +00006440static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006441posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006442{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006443#ifdef HAVE_LSTAT
Victor Stinner4195b5c2012-02-08 23:03:19 +01006444 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006445#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006446#ifdef MS_WINDOWS
Victor Stinner4195b5c2012-02-08 23:03:19 +01006447 return posix_do_stat(self, args, "O&:lstat", win32_lstat, "U:lstat",
Brian Curtind40e6f72010-07-08 21:39:08 +00006448 win32_lstat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006449#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01006450 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006451#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006452#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006453}
6454
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006455
Guido van Rossumb6775db1994-08-01 11:34:53 +00006456#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006457PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006458"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006459Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006460
Barry Warsaw53699e91996-12-10 23:23:01 +00006461static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006462posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006463{
Victor Stinner8c62be82010-05-06 00:08:46 +00006464 PyObject* v;
6465 char buf[MAXPATHLEN];
6466 PyObject *opath;
6467 char *path;
6468 int n;
6469 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00006470
Victor Stinner8c62be82010-05-06 00:08:46 +00006471 if (!PyArg_ParseTuple(args, "O&:readlink",
6472 PyUnicode_FSConverter, &opath))
6473 return NULL;
6474 path = PyBytes_AsString(opath);
6475 v = PySequence_GetItem(args, 0);
6476 if (v == NULL) {
6477 Py_DECREF(opath);
6478 return NULL;
6479 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00006480
Victor Stinner8c62be82010-05-06 00:08:46 +00006481 if (PyUnicode_Check(v)) {
6482 arg_is_unicode = 1;
6483 }
6484 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00006485
Victor Stinner8c62be82010-05-06 00:08:46 +00006486 Py_BEGIN_ALLOW_THREADS
6487 n = readlink(path, buf, (int) sizeof buf);
6488 Py_END_ALLOW_THREADS
6489 if (n < 0)
6490 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00006491
Victor Stinner8c62be82010-05-06 00:08:46 +00006492 Py_DECREF(opath);
Victor Stinnera45598a2010-05-14 16:35:39 +00006493 if (arg_is_unicode)
6494 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
6495 else
6496 return PyBytes_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006497}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006498#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006499
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006500
Brian Curtin52173d42010-12-02 18:29:18 +00006501#if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006502PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006503"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006504Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006505
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006506static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006507posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006508{
Victor Stinner8c62be82010-05-06 00:08:46 +00006509 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006510}
6511#endif /* HAVE_SYMLINK */
6512
Brian Curtind40e6f72010-07-08 21:39:08 +00006513#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
6514
6515PyDoc_STRVAR(win_readlink__doc__,
6516"readlink(path) -> path\n\n\
6517Return a string representing the path to which the symbolic link points.");
6518
Brian Curtind40e6f72010-07-08 21:39:08 +00006519/* Windows readlink implementation */
6520static PyObject *
6521win_readlink(PyObject *self, PyObject *args)
6522{
6523 wchar_t *path;
6524 DWORD n_bytes_returned;
6525 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006526 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00006527 HANDLE reparse_point_handle;
6528
6529 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
6530 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
6531 wchar_t *print_name;
6532
6533 if (!PyArg_ParseTuple(args,
Victor Stinnereb5657a2011-09-30 01:44:27 +02006534 "U:readlink",
6535 &po))
6536 return NULL;
6537 path = PyUnicode_AsUnicode(po);
6538 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00006539 return NULL;
6540
6541 /* First get a handle to the reparse point */
6542 Py_BEGIN_ALLOW_THREADS
6543 reparse_point_handle = CreateFileW(
6544 path,
6545 0,
6546 0,
6547 0,
6548 OPEN_EXISTING,
6549 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
6550 0);
6551 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006552
Brian Curtind40e6f72010-07-08 21:39:08 +00006553 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006554 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006555
Brian Curtind40e6f72010-07-08 21:39:08 +00006556 Py_BEGIN_ALLOW_THREADS
6557 /* New call DeviceIoControl to read the reparse point */
6558 io_result = DeviceIoControl(
6559 reparse_point_handle,
6560 FSCTL_GET_REPARSE_POINT,
6561 0, 0, /* in buffer */
6562 target_buffer, sizeof(target_buffer),
6563 &n_bytes_returned,
6564 0 /* we're not using OVERLAPPED_IO */
6565 );
6566 CloseHandle(reparse_point_handle);
6567 Py_END_ALLOW_THREADS
6568
6569 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006570 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00006571
6572 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
6573 {
6574 PyErr_SetString(PyExc_ValueError,
6575 "not a symbolic link");
6576 return NULL;
6577 }
Brian Curtin74e45612010-07-09 15:58:59 +00006578 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
6579 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
6580
6581 result = PyUnicode_FromWideChar(print_name,
6582 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00006583 return result;
6584}
6585
6586#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
6587
Brian Curtin52173d42010-12-02 18:29:18 +00006588#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtind40e6f72010-07-08 21:39:08 +00006589
6590/* Grab CreateSymbolicLinkW dynamically from kernel32 */
6591static int has_CreateSymbolicLinkW = 0;
6592static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD);
6593static int
6594check_CreateSymbolicLinkW()
6595{
6596 HINSTANCE hKernel32;
6597 /* only recheck */
6598 if (has_CreateSymbolicLinkW)
6599 return has_CreateSymbolicLinkW;
Martin v. Löwis50590f12012-01-14 17:54:09 +01006600 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtin74e45612010-07-09 15:58:59 +00006601 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
6602 "CreateSymbolicLinkW");
Brian Curtind40e6f72010-07-08 21:39:08 +00006603 if (Py_CreateSymbolicLinkW)
6604 has_CreateSymbolicLinkW = 1;
6605 return has_CreateSymbolicLinkW;
6606}
6607
6608PyDoc_STRVAR(win_symlink__doc__,
6609"symlink(src, dst, target_is_directory=False)\n\n\
6610Create a symbolic link pointing to src named dst.\n\
6611target_is_directory is required if the target is to be interpreted as\n\
6612a directory.\n\
6613This function requires Windows 6.0 or greater, and raises a\n\
6614NotImplementedError otherwise.");
6615
6616static PyObject *
6617win_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
6618{
6619 static char *kwlist[] = {"src", "dest", "target_is_directory", NULL};
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006620 PyObject *osrc, *odest;
6621 PyObject *usrc = NULL, *udest = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006622 wchar_t *wsrc, *wdest;
Brian Curtind40e6f72010-07-08 21:39:08 +00006623 int target_is_directory = 0;
6624 DWORD res;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006625
Brian Curtind40e6f72010-07-08 21:39:08 +00006626 if (!check_CreateSymbolicLinkW())
6627 {
6628 /* raise NotImplementedError */
6629 return PyErr_Format(PyExc_NotImplementedError,
6630 "CreateSymbolicLinkW not found");
6631 }
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006632 if (!PyArg_ParseTupleAndKeywords(
6633 args, kwargs, "OO|i:symlink", kwlist,
6634 &osrc, &odest, &target_is_directory))
Brian Curtind40e6f72010-07-08 21:39:08 +00006635 return NULL;
Brian Curtin3b4499c2010-12-28 14:31:47 +00006636
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006637 usrc = win32_decode_filename(osrc);
6638 if (!usrc)
6639 return NULL;
6640 udest = win32_decode_filename(odest);
6641 if (!udest)
6642 goto error;
6643
Brian Curtin3b4499c2010-12-28 14:31:47 +00006644 if (win32_can_symlink == 0)
6645 return PyErr_Format(PyExc_OSError, "symbolic link privilege not held");
6646
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006647 wsrc = PyUnicode_AsUnicode(usrc);
Victor Stinnereb5657a2011-09-30 01:44:27 +02006648 if (wsrc == NULL)
6649 goto error;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006650 wdest = PyUnicode_AsUnicode(udest);
Victor Stinnereb5657a2011-09-30 01:44:27 +02006651 if (wsrc == NULL)
6652 goto error;
6653
Brian Curtind40e6f72010-07-08 21:39:08 +00006654 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006655 res = Py_CreateSymbolicLinkW(wdest, wsrc, target_is_directory);
Brian Curtind40e6f72010-07-08 21:39:08 +00006656 Py_END_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006657
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006658 Py_DECREF(usrc);
6659 Py_DECREF(udest);
Brian Curtind40e6f72010-07-08 21:39:08 +00006660 if (!res)
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006661 return win32_error_object("symlink", osrc);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006662
Brian Curtind40e6f72010-07-08 21:39:08 +00006663 Py_INCREF(Py_None);
6664 return Py_None;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006665
6666error:
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006667 Py_XDECREF(usrc);
6668 Py_XDECREF(udest);
Victor Stinnereb5657a2011-09-30 01:44:27 +02006669 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00006670}
Brian Curtin52173d42010-12-02 18:29:18 +00006671#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006672
6673#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006674#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6675static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006676system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006677{
6678 ULONG value = 0;
6679
6680 Py_BEGIN_ALLOW_THREADS
6681 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6682 Py_END_ALLOW_THREADS
6683
6684 return value;
6685}
6686
6687static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006688posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006689{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006690 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner8c62be82010-05-06 00:08:46 +00006691 return Py_BuildValue("ddddd",
6692 (double)0 /* t.tms_utime / HZ */,
6693 (double)0 /* t.tms_stime / HZ */,
6694 (double)0 /* t.tms_cutime / HZ */,
6695 (double)0 /* t.tms_cstime / HZ */,
6696 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006697}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006698#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00006699#define NEED_TICKS_PER_SECOND
6700static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006701static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006702posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006703{
Victor Stinner8c62be82010-05-06 00:08:46 +00006704 struct tms t;
6705 clock_t c;
6706 errno = 0;
6707 c = times(&t);
6708 if (c == (clock_t) -1)
6709 return posix_error();
6710 return Py_BuildValue("ddddd",
6711 (double)t.tms_utime / ticks_per_second,
6712 (double)t.tms_stime / ticks_per_second,
6713 (double)t.tms_cutime / ticks_per_second,
6714 (double)t.tms_cstime / ticks_per_second,
6715 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006716}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006717#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006718#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006719
6720
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006721#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006722#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006723static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006724posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006725{
Victor Stinner8c62be82010-05-06 00:08:46 +00006726 FILETIME create, exit, kernel, user;
6727 HANDLE hProc;
6728 hProc = GetCurrentProcess();
6729 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6730 /* The fields of a FILETIME structure are the hi and lo part
6731 of a 64-bit value expressed in 100 nanosecond units.
6732 1e7 is one second in such units; 1e-7 the inverse.
6733 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6734 */
6735 return Py_BuildValue(
6736 "ddddd",
6737 (double)(user.dwHighDateTime*429.4967296 +
6738 user.dwLowDateTime*1e-7),
6739 (double)(kernel.dwHighDateTime*429.4967296 +
6740 kernel.dwLowDateTime*1e-7),
6741 (double)0,
6742 (double)0,
6743 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006744}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006745#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006746
6747#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006748PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006749"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006750Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006751#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006752
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006753
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006754#ifdef HAVE_GETSID
6755PyDoc_STRVAR(posix_getsid__doc__,
6756"getsid(pid) -> sid\n\n\
6757Call the system call getsid().");
6758
6759static PyObject *
6760posix_getsid(PyObject *self, PyObject *args)
6761{
Victor Stinner8c62be82010-05-06 00:08:46 +00006762 pid_t pid;
6763 int sid;
6764 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
6765 return NULL;
6766 sid = getsid(pid);
6767 if (sid < 0)
6768 return posix_error();
6769 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006770}
6771#endif /* HAVE_GETSID */
6772
6773
Guido van Rossumb6775db1994-08-01 11:34:53 +00006774#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006775PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006776"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006777Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006778
Barry Warsaw53699e91996-12-10 23:23:01 +00006779static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006780posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006781{
Victor Stinner8c62be82010-05-06 00:08:46 +00006782 if (setsid() < 0)
6783 return posix_error();
6784 Py_INCREF(Py_None);
6785 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006786}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006787#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006788
Guido van Rossumb6775db1994-08-01 11:34:53 +00006789#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006790PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006791"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006792Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006793
Barry Warsaw53699e91996-12-10 23:23:01 +00006794static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006795posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006796{
Victor Stinner8c62be82010-05-06 00:08:46 +00006797 pid_t pid;
6798 int pgrp;
6799 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
6800 return NULL;
6801 if (setpgid(pid, pgrp) < 0)
6802 return posix_error();
6803 Py_INCREF(Py_None);
6804 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006805}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006806#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006807
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006808
Guido van Rossumb6775db1994-08-01 11:34:53 +00006809#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006810PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006811"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006812Return the process group associated with the terminal given by a fd.");
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_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006816{
Victor Stinner8c62be82010-05-06 00:08:46 +00006817 int fd;
6818 pid_t pgid;
6819 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6820 return NULL;
6821 pgid = tcgetpgrp(fd);
6822 if (pgid < 0)
6823 return posix_error();
6824 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006825}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006826#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006827
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006828
Guido van Rossumb6775db1994-08-01 11:34:53 +00006829#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006830PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006831"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006832Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006833
Barry Warsaw53699e91996-12-10 23:23:01 +00006834static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006835posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006836{
Victor Stinner8c62be82010-05-06 00:08:46 +00006837 int fd;
6838 pid_t pgid;
6839 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
6840 return NULL;
6841 if (tcsetpgrp(fd, pgid) < 0)
6842 return posix_error();
6843 Py_INCREF(Py_None);
6844 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006845}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006846#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006847
Guido van Rossum687dd131993-05-17 08:34:16 +00006848/* Functions acting on file descriptors */
6849
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006850PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006851"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006852Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006853
Barry Warsaw53699e91996-12-10 23:23:01 +00006854static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006855posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006856{
Victor Stinner8c62be82010-05-06 00:08:46 +00006857 PyObject *ofile;
6858 char *file;
6859 int flag;
6860 int mode = 0777;
6861 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006862
6863#ifdef MS_WINDOWS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006864 PyObject *po;
Victor Stinner26de69d2011-06-17 15:15:38 +02006865 if (PyArg_ParseTuple(args, "Ui|i:open", &po, &flag, &mode)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02006866 wchar_t *wpath = PyUnicode_AsUnicode(po);
6867 if (wpath == NULL)
6868 return NULL;
6869
Victor Stinner8c62be82010-05-06 00:08:46 +00006870 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006871 fd = _wopen(wpath, flag, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00006872 Py_END_ALLOW_THREADS
6873 if (fd < 0)
6874 return posix_error();
6875 return PyLong_FromLong((long)fd);
6876 }
6877 /* Drop the argument parsing error as narrow strings
6878 are also valid. */
6879 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006880#endif
6881
Victor Stinner26de69d2011-06-17 15:15:38 +02006882 if (!PyArg_ParseTuple(args, "O&i|i:open",
Victor Stinner8c62be82010-05-06 00:08:46 +00006883 PyUnicode_FSConverter, &ofile,
6884 &flag, &mode))
6885 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006886#ifdef MS_WINDOWS
6887 if (win32_warn_bytes_api()) {
6888 Py_DECREF(ofile);
6889 return NULL;
6890 }
6891#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006892 file = PyBytes_AsString(ofile);
6893 Py_BEGIN_ALLOW_THREADS
6894 fd = open(file, flag, mode);
6895 Py_END_ALLOW_THREADS
6896 if (fd < 0)
6897 return posix_error_with_allocated_filename(ofile);
6898 Py_DECREF(ofile);
6899 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006900}
6901
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006902
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006903PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006904"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006905Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006906
Barry Warsaw53699e91996-12-10 23:23:01 +00006907static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006908posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006909{
Victor Stinner8c62be82010-05-06 00:08:46 +00006910 int fd, res;
6911 if (!PyArg_ParseTuple(args, "i:close", &fd))
6912 return NULL;
6913 if (!_PyVerify_fd(fd))
6914 return posix_error();
6915 Py_BEGIN_ALLOW_THREADS
6916 res = close(fd);
6917 Py_END_ALLOW_THREADS
6918 if (res < 0)
6919 return posix_error();
6920 Py_INCREF(Py_None);
6921 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006922}
6923
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006924
Victor Stinner8c62be82010-05-06 00:08:46 +00006925PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00006926"closerange(fd_low, fd_high)\n\n\
6927Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6928
6929static PyObject *
6930posix_closerange(PyObject *self, PyObject *args)
6931{
Victor Stinner8c62be82010-05-06 00:08:46 +00006932 int fd_from, fd_to, i;
6933 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6934 return NULL;
6935 Py_BEGIN_ALLOW_THREADS
6936 for (i = fd_from; i < fd_to; i++)
6937 if (_PyVerify_fd(i))
6938 close(i);
6939 Py_END_ALLOW_THREADS
6940 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00006941}
6942
6943
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006944PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006945"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006946Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006947
Barry Warsaw53699e91996-12-10 23:23:01 +00006948static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006949posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006950{
Victor Stinner8c62be82010-05-06 00:08:46 +00006951 int fd;
6952 if (!PyArg_ParseTuple(args, "i:dup", &fd))
6953 return NULL;
6954 if (!_PyVerify_fd(fd))
6955 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006956 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00006957 if (fd < 0)
6958 return posix_error();
6959 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006960}
6961
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006962
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006963PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006964"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006965Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006966
Barry Warsaw53699e91996-12-10 23:23:01 +00006967static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006968posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006969{
Victor Stinner8c62be82010-05-06 00:08:46 +00006970 int fd, fd2, res;
6971 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
6972 return NULL;
6973 if (!_PyVerify_fd_dup2(fd, fd2))
6974 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006975 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00006976 if (res < 0)
6977 return posix_error();
6978 Py_INCREF(Py_None);
6979 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006980}
6981
Ross Lagerwall7807c352011-03-17 20:20:30 +02006982#ifdef HAVE_LOCKF
6983PyDoc_STRVAR(posix_lockf__doc__,
6984"lockf(fd, cmd, len)\n\n\
6985Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
6986fd is an open file descriptor.\n\
6987cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
6988F_TEST.\n\
6989len specifies the section of the file to lock.");
6990
6991static PyObject *
6992posix_lockf(PyObject *self, PyObject *args)
6993{
6994 int fd, cmd, res;
6995 off_t len;
6996 if (!PyArg_ParseTuple(args, "iiO&:lockf",
6997 &fd, &cmd, _parse_off_t, &len))
6998 return NULL;
6999
7000 Py_BEGIN_ALLOW_THREADS
7001 res = lockf(fd, cmd, len);
7002 Py_END_ALLOW_THREADS
7003
7004 if (res < 0)
7005 return posix_error();
7006
7007 Py_RETURN_NONE;
7008}
7009#endif
7010
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007011
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007012PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007013"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007014Set the current position of a file descriptor.\n\
7015Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007016
Barry Warsaw53699e91996-12-10 23:23:01 +00007017static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007018posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007019{
Victor Stinner8c62be82010-05-06 00:08:46 +00007020 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007021#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007022 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007023#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007024 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007025#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007026 PyObject *posobj;
7027 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007028 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007029#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007030 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7031 switch (how) {
7032 case 0: how = SEEK_SET; break;
7033 case 1: how = SEEK_CUR; break;
7034 case 2: how = SEEK_END; break;
7035 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007036#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007037
Ross Lagerwall8e749672011-03-17 21:54:07 +02007038#if !defined(HAVE_LARGEFILE_SUPPORT)
7039 pos = PyLong_AsLong(posobj);
7040#else
7041 pos = PyLong_AsLongLong(posobj);
7042#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007043 if (PyErr_Occurred())
7044 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007045
Victor Stinner8c62be82010-05-06 00:08:46 +00007046 if (!_PyVerify_fd(fd))
7047 return posix_error();
7048 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007049#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007050 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007051#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007052 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007053#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007054 Py_END_ALLOW_THREADS
7055 if (res < 0)
7056 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007057
7058#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007059 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007060#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007061 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007062#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007063}
7064
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007065
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007066PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007067"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007068Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007069
Barry Warsaw53699e91996-12-10 23:23:01 +00007070static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007071posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007072{
Victor Stinner8c62be82010-05-06 00:08:46 +00007073 int fd, size;
7074 Py_ssize_t n;
7075 PyObject *buffer;
7076 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7077 return NULL;
7078 if (size < 0) {
7079 errno = EINVAL;
7080 return posix_error();
7081 }
7082 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7083 if (buffer == NULL)
7084 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007085 if (!_PyVerify_fd(fd)) {
7086 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007087 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007088 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007089 Py_BEGIN_ALLOW_THREADS
7090 n = read(fd, PyBytes_AS_STRING(buffer), size);
7091 Py_END_ALLOW_THREADS
7092 if (n < 0) {
7093 Py_DECREF(buffer);
7094 return posix_error();
7095 }
7096 if (n != size)
7097 _PyBytes_Resize(&buffer, n);
7098 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007099}
7100
Ross Lagerwall7807c352011-03-17 20:20:30 +02007101#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7102 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007103static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007104iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7105{
7106 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007107 Py_ssize_t blen, total = 0;
7108
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007109 *iov = PyMem_New(struct iovec, cnt);
7110 if (*iov == NULL) {
7111 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007112 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007113 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007114
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007115 *buf = PyMem_New(Py_buffer, cnt);
7116 if (*buf == NULL) {
7117 PyMem_Del(*iov);
7118 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007119 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007120 }
7121
7122 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007123 PyObject *item = PySequence_GetItem(seq, i);
7124 if (item == NULL)
7125 goto fail;
7126 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7127 Py_DECREF(item);
7128 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007129 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007130 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007131 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007132 blen = (*buf)[i].len;
7133 (*iov)[i].iov_len = blen;
7134 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007135 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007136 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007137
7138fail:
7139 PyMem_Del(*iov);
7140 for (j = 0; j < i; j++) {
7141 PyBuffer_Release(&(*buf)[j]);
7142 }
7143 PyMem_Del(*buf);
7144 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007145}
7146
7147static void
7148iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7149{
7150 int i;
7151 PyMem_Del(iov);
7152 for (i = 0; i < cnt; i++) {
7153 PyBuffer_Release(&buf[i]);
7154 }
7155 PyMem_Del(buf);
7156}
7157#endif
7158
Ross Lagerwall7807c352011-03-17 20:20:30 +02007159#ifdef HAVE_READV
7160PyDoc_STRVAR(posix_readv__doc__,
7161"readv(fd, buffers) -> bytesread\n\n\
7162Read from a file descriptor into a number of writable buffers. buffers\n\
7163is an arbitrary sequence of writable buffers.\n\
7164Returns the total number of bytes read.");
7165
7166static PyObject *
7167posix_readv(PyObject *self, PyObject *args)
7168{
7169 int fd, cnt;
7170 Py_ssize_t n;
7171 PyObject *seq;
7172 struct iovec *iov;
7173 Py_buffer *buf;
7174
7175 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7176 return NULL;
7177 if (!PySequence_Check(seq)) {
7178 PyErr_SetString(PyExc_TypeError,
7179 "readv() arg 2 must be a sequence");
7180 return NULL;
7181 }
7182 cnt = PySequence_Size(seq);
7183
7184 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7185 return NULL;
7186
7187 Py_BEGIN_ALLOW_THREADS
7188 n = readv(fd, iov, cnt);
7189 Py_END_ALLOW_THREADS
7190
7191 iov_cleanup(iov, buf, cnt);
7192 return PyLong_FromSsize_t(n);
7193}
7194#endif
7195
7196#ifdef HAVE_PREAD
7197PyDoc_STRVAR(posix_pread__doc__,
7198"pread(fd, buffersize, offset) -> string\n\n\
7199Read from a file descriptor, fd, at a position of offset. It will read up\n\
7200to buffersize number of bytes. The file offset remains unchanged.");
7201
7202static PyObject *
7203posix_pread(PyObject *self, PyObject *args)
7204{
7205 int fd, size;
7206 off_t offset;
7207 Py_ssize_t n;
7208 PyObject *buffer;
7209 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7210 return NULL;
7211
7212 if (size < 0) {
7213 errno = EINVAL;
7214 return posix_error();
7215 }
7216 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7217 if (buffer == NULL)
7218 return NULL;
7219 if (!_PyVerify_fd(fd)) {
7220 Py_DECREF(buffer);
7221 return posix_error();
7222 }
7223 Py_BEGIN_ALLOW_THREADS
7224 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7225 Py_END_ALLOW_THREADS
7226 if (n < 0) {
7227 Py_DECREF(buffer);
7228 return posix_error();
7229 }
7230 if (n != size)
7231 _PyBytes_Resize(&buffer, n);
7232 return buffer;
7233}
7234#endif
7235
7236PyDoc_STRVAR(posix_write__doc__,
7237"write(fd, string) -> byteswritten\n\n\
7238Write a string to a file descriptor.");
7239
7240static PyObject *
7241posix_write(PyObject *self, PyObject *args)
7242{
7243 Py_buffer pbuf;
7244 int fd;
7245 Py_ssize_t size, len;
7246
7247 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
7248 return NULL;
7249 if (!_PyVerify_fd(fd)) {
7250 PyBuffer_Release(&pbuf);
7251 return posix_error();
7252 }
7253 len = pbuf.len;
7254 Py_BEGIN_ALLOW_THREADS
7255#if defined(MS_WIN64) || defined(MS_WINDOWS)
7256 if (len > INT_MAX)
7257 len = INT_MAX;
7258 size = write(fd, pbuf.buf, (int)len);
7259#else
7260 size = write(fd, pbuf.buf, len);
7261#endif
7262 Py_END_ALLOW_THREADS
7263 PyBuffer_Release(&pbuf);
7264 if (size < 0)
7265 return posix_error();
7266 return PyLong_FromSsize_t(size);
7267}
7268
7269#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007270PyDoc_STRVAR(posix_sendfile__doc__,
7271"sendfile(out, in, offset, nbytes) -> byteswritten\n\
7272sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
7273 -> byteswritten\n\
7274Copy nbytes bytes from file descriptor in to file descriptor out.");
7275
7276static PyObject *
7277posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
7278{
7279 int in, out;
7280 Py_ssize_t ret;
7281 off_t offset;
7282
7283#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
7284#ifndef __APPLE__
7285 Py_ssize_t len;
7286#endif
7287 PyObject *headers = NULL, *trailers = NULL;
7288 Py_buffer *hbuf, *tbuf;
7289 off_t sbytes;
7290 struct sf_hdtr sf;
7291 int flags = 0;
7292 sf.headers = NULL;
7293 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00007294 static char *keywords[] = {"out", "in",
7295 "offset", "count",
7296 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007297
7298#ifdef __APPLE__
7299 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007300 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007301#else
7302 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007303 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007304#endif
7305 &headers, &trailers, &flags))
7306 return NULL;
7307 if (headers != NULL) {
7308 if (!PySequence_Check(headers)) {
7309 PyErr_SetString(PyExc_TypeError,
7310 "sendfile() headers must be a sequence or None");
7311 return NULL;
7312 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007313 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007314 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007315 if (sf.hdr_cnt > 0 &&
7316 !(i = iov_setup(&(sf.headers), &hbuf,
7317 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007318 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007319#ifdef __APPLE__
7320 sbytes += i;
7321#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007322 }
7323 }
7324 if (trailers != NULL) {
7325 if (!PySequence_Check(trailers)) {
7326 PyErr_SetString(PyExc_TypeError,
7327 "sendfile() trailers must be a sequence or None");
7328 return NULL;
7329 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007330 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007331 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007332 if (sf.trl_cnt > 0 &&
7333 !(i = iov_setup(&(sf.trailers), &tbuf,
7334 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007335 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007336#ifdef __APPLE__
7337 sbytes += i;
7338#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007339 }
7340 }
7341
7342 Py_BEGIN_ALLOW_THREADS
7343#ifdef __APPLE__
7344 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
7345#else
7346 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
7347#endif
7348 Py_END_ALLOW_THREADS
7349
7350 if (sf.headers != NULL)
7351 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
7352 if (sf.trailers != NULL)
7353 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
7354
7355 if (ret < 0) {
7356 if ((errno == EAGAIN) || (errno == EBUSY)) {
7357 if (sbytes != 0) {
7358 // some data has been sent
7359 goto done;
7360 }
7361 else {
7362 // no data has been sent; upper application is supposed
7363 // to retry on EAGAIN or EBUSY
7364 return posix_error();
7365 }
7366 }
7367 return posix_error();
7368 }
7369 goto done;
7370
7371done:
7372 #if !defined(HAVE_LARGEFILE_SUPPORT)
7373 return Py_BuildValue("l", sbytes);
7374 #else
7375 return Py_BuildValue("L", sbytes);
7376 #endif
7377
7378#else
7379 Py_ssize_t count;
7380 PyObject *offobj;
7381 static char *keywords[] = {"out", "in",
7382 "offset", "count", NULL};
7383 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
7384 keywords, &out, &in, &offobj, &count))
7385 return NULL;
7386#ifdef linux
7387 if (offobj == Py_None) {
7388 Py_BEGIN_ALLOW_THREADS
7389 ret = sendfile(out, in, NULL, count);
7390 Py_END_ALLOW_THREADS
7391 if (ret < 0)
7392 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02007393 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007394 }
7395#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00007396 if (!_parse_off_t(offobj, &offset))
7397 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007398 Py_BEGIN_ALLOW_THREADS
7399 ret = sendfile(out, in, &offset, count);
7400 Py_END_ALLOW_THREADS
7401 if (ret < 0)
7402 return posix_error();
7403 return Py_BuildValue("n", ret);
7404#endif
7405}
7406#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007407
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007408PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007409"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007410Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007411
Barry Warsaw53699e91996-12-10 23:23:01 +00007412static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007413posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007414{
Victor Stinner8c62be82010-05-06 00:08:46 +00007415 int fd;
7416 STRUCT_STAT st;
7417 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01007418 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007419 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007420#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00007421 /* on OpenVMS we must ensure that all bytes are written to the file */
7422 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007423#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007424 if (!_PyVerify_fd(fd))
7425 return posix_error();
7426 Py_BEGIN_ALLOW_THREADS
7427 res = FSTAT(fd, &st);
7428 Py_END_ALLOW_THREADS
7429 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00007430#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007431 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00007432#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007433 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00007434#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007435 }
Tim Peters5aa91602002-01-30 05:46:57 +00007436
Victor Stinner4195b5c2012-02-08 23:03:19 +01007437 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00007438}
7439
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007440PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007441"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007442Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007443connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00007444
7445static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00007446posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00007447{
Victor Stinner8c62be82010-05-06 00:08:46 +00007448 int fd;
7449 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
7450 return NULL;
7451 if (!_PyVerify_fd(fd))
7452 return PyBool_FromLong(0);
7453 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00007454}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007455
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007456#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007457PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007458"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007459Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007460
Barry Warsaw53699e91996-12-10 23:23:01 +00007461static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007462posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007463{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007464#if defined(PYOS_OS2)
7465 HFILE read, write;
7466 APIRET rc;
7467
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007468 rc = DosCreatePipe( &read, &write, 4096);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007469 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007470 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007471
7472 return Py_BuildValue("(ii)", read, write);
7473#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007474#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007475 int fds[2];
7476 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007477 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00007478 if (res != 0)
7479 return posix_error();
7480 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007481#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007482 HANDLE read, write;
7483 int read_fd, write_fd;
7484 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00007485 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00007486 if (!ok)
7487 return win32_error("CreatePipe", NULL);
7488 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
7489 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
7490 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007491#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007492#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007493}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007494#endif /* HAVE_PIPE */
7495
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007496#ifdef HAVE_PIPE2
7497PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02007498"pipe2(flags) -> (read_end, write_end)\n\n\
7499Create a pipe with flags set atomically.\n\
7500flags can be constructed by ORing together one or more of these values:\n\
7501O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007502");
7503
7504static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02007505posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007506{
Charles-François Natali368f34b2011-06-06 19:49:47 +02007507 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007508 int fds[2];
7509 int res;
7510
Charles-François Natali368f34b2011-06-06 19:49:47 +02007511 flags = PyLong_AsLong(arg);
7512 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007513 return NULL;
7514
7515 res = pipe2(fds, flags);
7516 if (res != 0)
7517 return posix_error();
7518 return Py_BuildValue("(ii)", fds[0], fds[1]);
7519}
7520#endif /* HAVE_PIPE2 */
7521
Ross Lagerwall7807c352011-03-17 20:20:30 +02007522#ifdef HAVE_WRITEV
7523PyDoc_STRVAR(posix_writev__doc__,
7524"writev(fd, buffers) -> byteswritten\n\n\
7525Write the contents of buffers to a file descriptor, where buffers is an\n\
7526arbitrary sequence of buffers.\n\
7527Returns the total bytes written.");
7528
7529static PyObject *
7530posix_writev(PyObject *self, PyObject *args)
7531{
7532 int fd, cnt;
7533 Py_ssize_t res;
7534 PyObject *seq;
7535 struct iovec *iov;
7536 Py_buffer *buf;
7537 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
7538 return NULL;
7539 if (!PySequence_Check(seq)) {
7540 PyErr_SetString(PyExc_TypeError,
7541 "writev() arg 2 must be a sequence");
7542 return NULL;
7543 }
7544 cnt = PySequence_Size(seq);
7545
7546 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
7547 return NULL;
7548 }
7549
7550 Py_BEGIN_ALLOW_THREADS
7551 res = writev(fd, iov, cnt);
7552 Py_END_ALLOW_THREADS
7553
7554 iov_cleanup(iov, buf, cnt);
7555 return PyLong_FromSsize_t(res);
7556}
7557#endif
7558
7559#ifdef HAVE_PWRITE
7560PyDoc_STRVAR(posix_pwrite__doc__,
7561"pwrite(fd, string, offset) -> byteswritten\n\n\
7562Write string to a file descriptor, fd, from offset, leaving the file\n\
7563offset unchanged.");
7564
7565static PyObject *
7566posix_pwrite(PyObject *self, PyObject *args)
7567{
7568 Py_buffer pbuf;
7569 int fd;
7570 off_t offset;
7571 Py_ssize_t size;
7572
7573 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
7574 return NULL;
7575
7576 if (!_PyVerify_fd(fd)) {
7577 PyBuffer_Release(&pbuf);
7578 return posix_error();
7579 }
7580 Py_BEGIN_ALLOW_THREADS
7581 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
7582 Py_END_ALLOW_THREADS
7583 PyBuffer_Release(&pbuf);
7584 if (size < 0)
7585 return posix_error();
7586 return PyLong_FromSsize_t(size);
7587}
7588#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007589
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007590#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007591PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007592"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007593Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007594
Barry Warsaw53699e91996-12-10 23:23:01 +00007595static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007596posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007597{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007598 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00007599 char *filename;
7600 int mode = 0666;
7601 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007602 if (!PyArg_ParseTuple(args, "O&|i:mkfifo", PyUnicode_FSConverter, &opath,
7603 &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00007604 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007605 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007606 Py_BEGIN_ALLOW_THREADS
7607 res = mkfifo(filename, mode);
7608 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007609 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007610 if (res < 0)
7611 return posix_error();
7612 Py_INCREF(Py_None);
7613 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007614}
7615#endif
7616
7617
Neal Norwitz11690112002-07-30 01:08:28 +00007618#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007619PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007620"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007621Create a filesystem node (file, device special file or named pipe)\n\
7622named filename. mode specifies both the permissions to use and the\n\
7623type of node to be created, being combined (bitwise OR) with one of\n\
7624S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007625device defines the newly created device special file (probably using\n\
7626os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007627
7628
7629static PyObject *
7630posix_mknod(PyObject *self, PyObject *args)
7631{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007632 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00007633 char *filename;
7634 int mode = 0600;
7635 int device = 0;
7636 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007637 if (!PyArg_ParseTuple(args, "O&|ii:mknod", PyUnicode_FSConverter, &opath,
7638 &mode, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00007639 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007640 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007641 Py_BEGIN_ALLOW_THREADS
7642 res = mknod(filename, mode, device);
7643 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007644 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007645 if (res < 0)
7646 return posix_error();
7647 Py_INCREF(Py_None);
7648 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007649}
7650#endif
7651
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007652#ifdef HAVE_DEVICE_MACROS
7653PyDoc_STRVAR(posix_major__doc__,
7654"major(device) -> major number\n\
7655Extracts a device major number from a raw device number.");
7656
7657static PyObject *
7658posix_major(PyObject *self, PyObject *args)
7659{
Victor Stinner8c62be82010-05-06 00:08:46 +00007660 int device;
7661 if (!PyArg_ParseTuple(args, "i:major", &device))
7662 return NULL;
7663 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007664}
7665
7666PyDoc_STRVAR(posix_minor__doc__,
7667"minor(device) -> minor number\n\
7668Extracts a device minor number from a raw device number.");
7669
7670static PyObject *
7671posix_minor(PyObject *self, PyObject *args)
7672{
Victor Stinner8c62be82010-05-06 00:08:46 +00007673 int device;
7674 if (!PyArg_ParseTuple(args, "i:minor", &device))
7675 return NULL;
7676 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007677}
7678
7679PyDoc_STRVAR(posix_makedev__doc__,
7680"makedev(major, minor) -> device number\n\
7681Composes a raw device number from the major and minor device numbers.");
7682
7683static PyObject *
7684posix_makedev(PyObject *self, PyObject *args)
7685{
Victor Stinner8c62be82010-05-06 00:08:46 +00007686 int major, minor;
7687 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
7688 return NULL;
7689 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007690}
7691#endif /* device macros */
7692
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007693
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007694#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007695PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007696"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007697Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007698
Barry Warsaw53699e91996-12-10 23:23:01 +00007699static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007700posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007701{
Victor Stinner8c62be82010-05-06 00:08:46 +00007702 int fd;
7703 off_t length;
7704 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007705
Ross Lagerwall7807c352011-03-17 20:20:30 +02007706 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00007707 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007708
Victor Stinner8c62be82010-05-06 00:08:46 +00007709 Py_BEGIN_ALLOW_THREADS
7710 res = ftruncate(fd, length);
7711 Py_END_ALLOW_THREADS
7712 if (res < 0)
7713 return posix_error();
7714 Py_INCREF(Py_None);
7715 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007716}
7717#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007718
Ross Lagerwall7807c352011-03-17 20:20:30 +02007719#ifdef HAVE_TRUNCATE
7720PyDoc_STRVAR(posix_truncate__doc__,
7721"truncate(path, length)\n\n\
7722Truncate the file given by path to length bytes.");
7723
7724static PyObject *
7725posix_truncate(PyObject *self, PyObject *args)
7726{
7727 PyObject *opath;
7728 const char *path;
7729 off_t length;
7730 int res;
7731
7732 if (!PyArg_ParseTuple(args, "O&O&:truncate",
7733 PyUnicode_FSConverter, &opath, _parse_off_t, &length))
7734 return NULL;
7735 path = PyBytes_AsString(opath);
7736
7737 Py_BEGIN_ALLOW_THREADS
7738 res = truncate(path, length);
7739 Py_END_ALLOW_THREADS
7740 Py_DECREF(opath);
7741 if (res < 0)
7742 return posix_error();
7743 Py_RETURN_NONE;
7744}
7745#endif
7746
7747#ifdef HAVE_POSIX_FALLOCATE
7748PyDoc_STRVAR(posix_posix_fallocate__doc__,
7749"posix_fallocate(fd, offset, len)\n\n\
7750Ensures that enough disk space is allocated for the file specified by fd\n\
7751starting from offset and continuing for len bytes.");
7752
7753static PyObject *
7754posix_posix_fallocate(PyObject *self, PyObject *args)
7755{
7756 off_t len, offset;
7757 int res, fd;
7758
7759 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
7760 &fd, _parse_off_t, &offset, _parse_off_t, &len))
7761 return NULL;
7762
7763 Py_BEGIN_ALLOW_THREADS
7764 res = posix_fallocate(fd, offset, len);
7765 Py_END_ALLOW_THREADS
7766 if (res != 0) {
7767 errno = res;
7768 return posix_error();
7769 }
7770 Py_RETURN_NONE;
7771}
7772#endif
7773
7774#ifdef HAVE_POSIX_FADVISE
7775PyDoc_STRVAR(posix_posix_fadvise__doc__,
7776"posix_fadvise(fd, offset, len, advice)\n\n\
7777Announces an intention to access data in a specific pattern thus allowing\n\
7778the kernel to make optimizations.\n\
7779The advice applies to the region of the file specified by fd starting at\n\
7780offset and continuing for len bytes.\n\
7781advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
7782POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
7783POSIX_FADV_DONTNEED.");
7784
7785static PyObject *
7786posix_posix_fadvise(PyObject *self, PyObject *args)
7787{
7788 off_t len, offset;
7789 int res, fd, advice;
7790
7791 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
7792 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
7793 return NULL;
7794
7795 Py_BEGIN_ALLOW_THREADS
7796 res = posix_fadvise(fd, offset, len, advice);
7797 Py_END_ALLOW_THREADS
7798 if (res != 0) {
7799 errno = res;
7800 return posix_error();
7801 }
7802 Py_RETURN_NONE;
7803}
7804#endif
7805
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007806#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007807PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007808"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007809Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007810
Fred Drake762e2061999-08-26 17:23:54 +00007811/* Save putenv() parameters as values here, so we can collect them when they
7812 * get re-set with another call for the same key. */
7813static PyObject *posix_putenv_garbage;
7814
Tim Peters5aa91602002-01-30 05:46:57 +00007815static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007816posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007817{
Victor Stinner84ae1182010-05-06 22:05:07 +00007818 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007819#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01007820 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007821 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01007822
Victor Stinner8c62be82010-05-06 00:08:46 +00007823 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01007824 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01007825 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00007826 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007827
Victor Stinner65170952011-11-22 22:16:17 +01007828 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00007829 if (newstr == NULL) {
7830 PyErr_NoMemory();
7831 goto error;
7832 }
Victor Stinner65170952011-11-22 22:16:17 +01007833 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
7834 PyErr_Format(PyExc_ValueError,
7835 "the environment variable is longer than %u characters",
7836 _MAX_ENV);
7837 goto error;
7838 }
7839
Victor Stinner8c62be82010-05-06 00:08:46 +00007840 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02007841 if (newenv == NULL)
7842 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007843 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007844 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00007845 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007846 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007847#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007848 PyObject *os1, *os2;
7849 char *s1, *s2;
7850 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007851
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007852 if (!PyArg_ParseTuple(args,
7853 "O&O&:putenv",
7854 PyUnicode_FSConverter, &os1,
7855 PyUnicode_FSConverter, &os2))
7856 return NULL;
7857 s1 = PyBytes_AsString(os1);
7858 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00007859
Victor Stinner65170952011-11-22 22:16:17 +01007860 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01007861 if (newstr == NULL) {
7862 PyErr_NoMemory();
7863 goto error;
7864 }
7865
Victor Stinner8c62be82010-05-06 00:08:46 +00007866 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00007867 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007868 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00007869 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007870 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007871#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007872
Victor Stinner8c62be82010-05-06 00:08:46 +00007873 /* Install the first arg and newstr in posix_putenv_garbage;
7874 * this will cause previous value to be collected. This has to
7875 * happen after the real putenv() call because the old value
7876 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01007877 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007878 /* really not much we can do; just leak */
7879 PyErr_Clear();
7880 }
7881 else {
7882 Py_DECREF(newstr);
7883 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00007884
Martin v. Löwis011e8422009-05-05 04:43:17 +00007885#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007886 Py_DECREF(os1);
7887 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00007888#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007889 Py_RETURN_NONE;
7890
7891error:
7892#ifndef MS_WINDOWS
7893 Py_DECREF(os1);
7894 Py_DECREF(os2);
7895#endif
7896 Py_XDECREF(newstr);
7897 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00007898}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007899#endif /* putenv */
7900
Guido van Rossumc524d952001-10-19 01:31:59 +00007901#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007902PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007903"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007904Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00007905
7906static PyObject *
7907posix_unsetenv(PyObject *self, PyObject *args)
7908{
Victor Stinner65170952011-11-22 22:16:17 +01007909 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01007910#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01007911 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01007912#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007913
7914 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00007915
Victor Stinner65170952011-11-22 22:16:17 +01007916 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00007917 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00007918
Victor Stinner984890f2011-11-24 13:53:38 +01007919#ifdef HAVE_BROKEN_UNSETENV
7920 unsetenv(PyBytes_AS_STRING(name));
7921#else
Victor Stinner65170952011-11-22 22:16:17 +01007922 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06007923 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06007924 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01007925 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06007926 }
Victor Stinner984890f2011-11-24 13:53:38 +01007927#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007928
Victor Stinner8c62be82010-05-06 00:08:46 +00007929 /* Remove the key from posix_putenv_garbage;
7930 * this will cause it to be collected. This has to
7931 * happen after the real unsetenv() call because the
7932 * old value was still accessible until then.
7933 */
Victor Stinner65170952011-11-22 22:16:17 +01007934 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007935 /* really not much we can do; just leak */
7936 PyErr_Clear();
7937 }
Victor Stinner65170952011-11-22 22:16:17 +01007938 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00007939 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00007940}
7941#endif /* unsetenv */
7942
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007943PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007944"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007945Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00007946
Guido van Rossumf68d8e52001-04-14 17:55:09 +00007947static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007948posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00007949{
Victor Stinner8c62be82010-05-06 00:08:46 +00007950 int code;
7951 char *message;
7952 if (!PyArg_ParseTuple(args, "i:strerror", &code))
7953 return NULL;
7954 message = strerror(code);
7955 if (message == NULL) {
7956 PyErr_SetString(PyExc_ValueError,
7957 "strerror() argument out of range");
7958 return NULL;
7959 }
Victor Stinner1b579672011-12-17 05:47:23 +01007960 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00007961}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007962
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007963
Guido van Rossumc9641791998-08-04 15:26:23 +00007964#ifdef HAVE_SYS_WAIT_H
7965
Fred Drake106c1a02002-04-23 15:58:02 +00007966#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007967PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007968"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007969Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00007970
7971static PyObject *
7972posix_WCOREDUMP(PyObject *self, PyObject *args)
7973{
Victor Stinner8c62be82010-05-06 00:08:46 +00007974 WAIT_TYPE status;
7975 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007976
Victor Stinner8c62be82010-05-06 00:08:46 +00007977 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
7978 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007979
Victor Stinner8c62be82010-05-06 00:08:46 +00007980 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007981}
7982#endif /* WCOREDUMP */
7983
7984#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007985PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007986"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007987Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007988job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00007989
7990static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007991posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00007992{
Victor Stinner8c62be82010-05-06 00:08:46 +00007993 WAIT_TYPE status;
7994 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007995
Victor Stinner8c62be82010-05-06 00:08:46 +00007996 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
7997 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007998
Victor Stinner8c62be82010-05-06 00:08:46 +00007999 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008000}
8001#endif /* WIFCONTINUED */
8002
Guido van Rossumc9641791998-08-04 15:26:23 +00008003#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008004PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008005"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008006Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008007
8008static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008009posix_WIFSTOPPED(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:WIFSTOPPED", &WAIT_STATUS_INT(status)))
8015 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008016
Victor Stinner8c62be82010-05-06 00:08:46 +00008017 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008018}
8019#endif /* WIFSTOPPED */
8020
8021#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008022PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008023"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008024Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008025
8026static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008027posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008028{
Victor Stinner8c62be82010-05-06 00:08:46 +00008029 WAIT_TYPE status;
8030 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008031
Victor Stinner8c62be82010-05-06 00:08:46 +00008032 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8033 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008034
Victor Stinner8c62be82010-05-06 00:08:46 +00008035 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008036}
8037#endif /* WIFSIGNALED */
8038
8039#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008040PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008041"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008042Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008043system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008044
8045static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008046posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008047{
Victor Stinner8c62be82010-05-06 00:08:46 +00008048 WAIT_TYPE status;
8049 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008050
Victor Stinner8c62be82010-05-06 00:08:46 +00008051 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
8052 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008053
Victor Stinner8c62be82010-05-06 00:08:46 +00008054 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008055}
8056#endif /* WIFEXITED */
8057
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008058#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008059PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008060"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008061Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008062
8063static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008064posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008065{
Victor Stinner8c62be82010-05-06 00:08:46 +00008066 WAIT_TYPE status;
8067 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008068
Victor Stinner8c62be82010-05-06 00:08:46 +00008069 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8070 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008071
Victor Stinner8c62be82010-05-06 00:08:46 +00008072 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008073}
8074#endif /* WEXITSTATUS */
8075
8076#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008077PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008078"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008079Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008080value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008081
8082static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008083posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008084{
Victor Stinner8c62be82010-05-06 00:08:46 +00008085 WAIT_TYPE status;
8086 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008087
Victor Stinner8c62be82010-05-06 00:08:46 +00008088 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8089 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008090
Victor Stinner8c62be82010-05-06 00:08:46 +00008091 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008092}
8093#endif /* WTERMSIG */
8094
8095#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008096PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008097"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008098Return the signal that stopped the process that provided\n\
8099the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008100
8101static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008102posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008103{
Victor Stinner8c62be82010-05-06 00:08:46 +00008104 WAIT_TYPE status;
8105 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008106
Victor Stinner8c62be82010-05-06 00:08:46 +00008107 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8108 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008109
Victor Stinner8c62be82010-05-06 00:08:46 +00008110 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008111}
8112#endif /* WSTOPSIG */
8113
8114#endif /* HAVE_SYS_WAIT_H */
8115
8116
Thomas Wouters477c8d52006-05-27 19:21:47 +00008117#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00008118#ifdef _SCO_DS
8119/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
8120 needed definitions in sys/statvfs.h */
8121#define _SVID3
8122#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008123#include <sys/statvfs.h>
8124
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008125static PyObject*
8126_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008127 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8128 if (v == NULL)
8129 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008130
8131#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008132 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8133 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8134 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8135 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8136 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8137 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8138 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8139 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8140 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8141 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008142#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008143 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8144 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8145 PyStructSequence_SET_ITEM(v, 2,
8146 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8147 PyStructSequence_SET_ITEM(v, 3,
8148 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8149 PyStructSequence_SET_ITEM(v, 4,
8150 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8151 PyStructSequence_SET_ITEM(v, 5,
8152 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8153 PyStructSequence_SET_ITEM(v, 6,
8154 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8155 PyStructSequence_SET_ITEM(v, 7,
8156 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
8157 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8158 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008159#endif
8160
Victor Stinner8c62be82010-05-06 00:08:46 +00008161 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008162}
8163
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008164PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008165"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008166Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008167
8168static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008169posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008170{
Victor Stinner8c62be82010-05-06 00:08:46 +00008171 int fd, res;
8172 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008173
Victor Stinner8c62be82010-05-06 00:08:46 +00008174 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
8175 return NULL;
8176 Py_BEGIN_ALLOW_THREADS
8177 res = fstatvfs(fd, &st);
8178 Py_END_ALLOW_THREADS
8179 if (res != 0)
8180 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008181
Victor Stinner8c62be82010-05-06 00:08:46 +00008182 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008183}
Thomas Wouters477c8d52006-05-27 19:21:47 +00008184#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008185
8186
Thomas Wouters477c8d52006-05-27 19:21:47 +00008187#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008188#include <sys/statvfs.h>
8189
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008190PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008191"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008192Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008193
8194static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008195posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008196{
Victor Stinner6fa67772011-09-20 04:04:33 +02008197 PyObject *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008198 int res;
8199 struct statvfs st;
Victor Stinner6fa67772011-09-20 04:04:33 +02008200 if (!PyArg_ParseTuple(args, "O&:statvfs", PyUnicode_FSConverter, &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00008201 return NULL;
8202 Py_BEGIN_ALLOW_THREADS
Victor Stinner6fa67772011-09-20 04:04:33 +02008203 res = statvfs(PyBytes_AS_STRING(path), &st);
Victor Stinner8c62be82010-05-06 00:08:46 +00008204 Py_END_ALLOW_THREADS
Victor Stinner6fa67772011-09-20 04:04:33 +02008205 if (res != 0) {
8206 posix_error_with_filename(PyBytes_AS_STRING(path));
8207 Py_DECREF(path);
8208 return NULL;
8209 }
8210 Py_DECREF(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008211
Victor Stinner8c62be82010-05-06 00:08:46 +00008212 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008213}
8214#endif /* HAVE_STATVFS */
8215
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008216#ifdef MS_WINDOWS
8217PyDoc_STRVAR(win32__getdiskusage__doc__,
8218"_getdiskusage(path) -> (total, free)\n\n\
8219Return disk usage statistics about the given path as (total, free) tuple.");
8220
8221static PyObject *
8222win32__getdiskusage(PyObject *self, PyObject *args)
8223{
8224 BOOL retval;
8225 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01008226 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008227
Victor Stinner6139c1b2011-11-09 22:14:14 +01008228 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008229 return NULL;
8230
8231 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01008232 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008233 Py_END_ALLOW_THREADS
8234 if (retval == 0)
8235 return PyErr_SetFromWindowsErr(0);
8236
8237 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
8238}
8239#endif
8240
8241
Fred Drakec9680921999-12-13 16:37:25 +00008242/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
8243 * It maps strings representing configuration variable names to
8244 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00008245 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00008246 * rarely-used constants. There are three separate tables that use
8247 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00008248 *
8249 * This code is always included, even if none of the interfaces that
8250 * need it are included. The #if hackery needed to avoid it would be
8251 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00008252 */
8253struct constdef {
8254 char *name;
8255 long value;
8256};
8257
Fred Drake12c6e2d1999-12-14 21:25:03 +00008258static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008259conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00008260 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00008261{
Christian Heimes217cfd12007-12-02 14:31:20 +00008262 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008263 *valuep = PyLong_AS_LONG(arg);
8264 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00008265 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00008266 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00008267 /* look up the value in the table using a binary search */
8268 size_t lo = 0;
8269 size_t mid;
8270 size_t hi = tablesize;
8271 int cmp;
8272 const char *confname;
8273 if (!PyUnicode_Check(arg)) {
8274 PyErr_SetString(PyExc_TypeError,
8275 "configuration names must be strings or integers");
8276 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008277 }
Stefan Krah0e803b32010-11-26 16:16:47 +00008278 confname = _PyUnicode_AsString(arg);
8279 if (confname == NULL)
8280 return 0;
8281 while (lo < hi) {
8282 mid = (lo + hi) / 2;
8283 cmp = strcmp(confname, table[mid].name);
8284 if (cmp < 0)
8285 hi = mid;
8286 else if (cmp > 0)
8287 lo = mid + 1;
8288 else {
8289 *valuep = table[mid].value;
8290 return 1;
8291 }
8292 }
8293 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
8294 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008295 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00008296}
8297
8298
8299#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
8300static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008301#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008302 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008303#endif
8304#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008305 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008306#endif
Fred Drakec9680921999-12-13 16:37:25 +00008307#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008308 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008309#endif
8310#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00008311 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00008312#endif
8313#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00008314 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00008315#endif
8316#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00008317 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00008318#endif
8319#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008320 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008321#endif
8322#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00008323 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00008324#endif
8325#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008326 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00008327#endif
8328#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008329 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008330#endif
8331#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008332 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00008333#endif
8334#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008335 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008336#endif
8337#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008338 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00008339#endif
8340#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008341 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008342#endif
8343#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008344 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00008345#endif
8346#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008347 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008348#endif
8349#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008350 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00008351#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00008352#ifdef _PC_ACL_ENABLED
8353 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
8354#endif
8355#ifdef _PC_MIN_HOLE_SIZE
8356 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
8357#endif
8358#ifdef _PC_ALLOC_SIZE_MIN
8359 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
8360#endif
8361#ifdef _PC_REC_INCR_XFER_SIZE
8362 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
8363#endif
8364#ifdef _PC_REC_MAX_XFER_SIZE
8365 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
8366#endif
8367#ifdef _PC_REC_MIN_XFER_SIZE
8368 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
8369#endif
8370#ifdef _PC_REC_XFER_ALIGN
8371 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
8372#endif
8373#ifdef _PC_SYMLINK_MAX
8374 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
8375#endif
8376#ifdef _PC_XATTR_ENABLED
8377 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
8378#endif
8379#ifdef _PC_XATTR_EXISTS
8380 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
8381#endif
8382#ifdef _PC_TIMESTAMP_RESOLUTION
8383 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
8384#endif
Fred Drakec9680921999-12-13 16:37:25 +00008385};
8386
Fred Drakec9680921999-12-13 16:37:25 +00008387static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008388conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008389{
8390 return conv_confname(arg, valuep, posix_constants_pathconf,
8391 sizeof(posix_constants_pathconf)
8392 / sizeof(struct constdef));
8393}
8394#endif
8395
8396#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008397PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008398"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008399Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008400If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00008401
8402static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008403posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008404{
8405 PyObject *result = NULL;
8406 int name, fd;
8407
Fred Drake12c6e2d1999-12-14 21:25:03 +00008408 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
8409 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008410 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008411
Stefan Krah0e803b32010-11-26 16:16:47 +00008412 errno = 0;
8413 limit = fpathconf(fd, name);
8414 if (limit == -1 && errno != 0)
8415 posix_error();
8416 else
8417 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008418 }
8419 return result;
8420}
8421#endif
8422
8423
8424#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008425PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008426"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008427Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008428If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00008429
8430static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008431posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008432{
8433 PyObject *result = NULL;
8434 int name;
8435 char *path;
8436
8437 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
8438 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008439 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008440
Victor Stinner8c62be82010-05-06 00:08:46 +00008441 errno = 0;
8442 limit = pathconf(path, name);
8443 if (limit == -1 && errno != 0) {
8444 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00008445 /* could be a path or name problem */
8446 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00008447 else
Stefan Krah99439262010-11-26 12:58:05 +00008448 posix_error_with_filename(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00008449 }
8450 else
8451 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008452 }
8453 return result;
8454}
8455#endif
8456
8457#ifdef HAVE_CONFSTR
8458static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008459#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00008460 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00008461#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00008462#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008463 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008464#endif
8465#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008466 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008467#endif
Fred Draked86ed291999-12-15 15:34:33 +00008468#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008469 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008470#endif
8471#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008472 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008473#endif
8474#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008475 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008476#endif
8477#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008478 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008479#endif
Fred Drakec9680921999-12-13 16:37:25 +00008480#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008481 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008482#endif
8483#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008484 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008485#endif
8486#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008487 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008488#endif
8489#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008490 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008491#endif
8492#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008493 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008494#endif
8495#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008496 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008497#endif
8498#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008499 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008500#endif
8501#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008502 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008503#endif
Fred Draked86ed291999-12-15 15:34:33 +00008504#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00008505 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00008506#endif
Fred Drakec9680921999-12-13 16:37:25 +00008507#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00008508 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00008509#endif
Fred Draked86ed291999-12-15 15:34:33 +00008510#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008511 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00008512#endif
8513#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008514 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00008515#endif
8516#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008517 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008518#endif
8519#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008520 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00008521#endif
Fred Drakec9680921999-12-13 16:37:25 +00008522#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008523 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008524#endif
8525#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008526 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008527#endif
8528#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008529 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008530#endif
8531#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008532 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008533#endif
8534#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008535 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008536#endif
8537#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008538 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008539#endif
8540#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008541 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008542#endif
8543#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008544 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008545#endif
8546#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008547 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008548#endif
8549#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008550 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008551#endif
8552#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008553 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008554#endif
8555#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008556 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008557#endif
8558#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008559 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008560#endif
8561#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008562 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008563#endif
8564#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008565 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008566#endif
8567#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008568 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008569#endif
Fred Draked86ed291999-12-15 15:34:33 +00008570#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008571 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008572#endif
8573#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008574 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00008575#endif
8576#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00008577 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00008578#endif
8579#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008580 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008581#endif
8582#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008583 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008584#endif
8585#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00008586 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00008587#endif
8588#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008589 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00008590#endif
8591#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00008592 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00008593#endif
8594#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008595 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008596#endif
8597#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008598 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008599#endif
8600#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008601 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008602#endif
8603#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008604 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008605#endif
8606#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00008607 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00008608#endif
Fred Drakec9680921999-12-13 16:37:25 +00008609};
8610
8611static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008612conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008613{
8614 return conv_confname(arg, valuep, posix_constants_confstr,
8615 sizeof(posix_constants_confstr)
8616 / sizeof(struct constdef));
8617}
8618
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008619PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008620"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008621Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008622
8623static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008624posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008625{
8626 PyObject *result = NULL;
8627 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00008628 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00008629 int len;
Fred Drakec9680921999-12-13 16:37:25 +00008630
Victor Stinnercb043522010-09-10 23:49:04 +00008631 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
8632 return NULL;
8633
8634 errno = 0;
8635 len = confstr(name, buffer, sizeof(buffer));
8636 if (len == 0) {
8637 if (errno) {
8638 posix_error();
8639 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00008640 }
8641 else {
Victor Stinnercb043522010-09-10 23:49:04 +00008642 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00008643 }
8644 }
Victor Stinnercb043522010-09-10 23:49:04 +00008645
8646 if ((unsigned int)len >= sizeof(buffer)) {
8647 char *buf = PyMem_Malloc(len);
8648 if (buf == NULL)
8649 return PyErr_NoMemory();
8650 confstr(name, buf, len);
8651 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
8652 PyMem_Free(buf);
8653 }
8654 else
8655 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00008656 return result;
8657}
8658#endif
8659
8660
8661#ifdef HAVE_SYSCONF
8662static struct constdef posix_constants_sysconf[] = {
8663#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008664 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00008665#endif
8666#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00008667 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00008668#endif
8669#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008670 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008671#endif
8672#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008673 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008674#endif
8675#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008676 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008677#endif
8678#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00008679 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00008680#endif
8681#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00008682 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00008683#endif
8684#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008685 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008686#endif
8687#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00008688 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00008689#endif
8690#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008691 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008692#endif
Fred Draked86ed291999-12-15 15:34:33 +00008693#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008694 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008695#endif
8696#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00008697 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00008698#endif
Fred Drakec9680921999-12-13 16:37:25 +00008699#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008700 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008701#endif
Fred Drakec9680921999-12-13 16:37:25 +00008702#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008703 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008704#endif
8705#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008706 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008707#endif
8708#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008709 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008710#endif
8711#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008712 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008713#endif
8714#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008715 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008716#endif
Fred Draked86ed291999-12-15 15:34:33 +00008717#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008718 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00008719#endif
Fred Drakec9680921999-12-13 16:37:25 +00008720#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00008721 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008722#endif
8723#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008724 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008725#endif
8726#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008727 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008728#endif
8729#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008730 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008731#endif
8732#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008733 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008734#endif
Fred Draked86ed291999-12-15 15:34:33 +00008735#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00008736 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00008737#endif
Fred Drakec9680921999-12-13 16:37:25 +00008738#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008739 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008740#endif
8741#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008742 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008743#endif
8744#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008745 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008746#endif
8747#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008748 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008749#endif
8750#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008751 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008752#endif
8753#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008754 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00008755#endif
8756#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008757 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008758#endif
8759#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008760 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008761#endif
8762#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00008763 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008764#endif
8765#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008766 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008767#endif
8768#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008769 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008770#endif
8771#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008772 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008773#endif
8774#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008775 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008776#endif
8777#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008778 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008779#endif
8780#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008781 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008782#endif
8783#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008784 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008785#endif
8786#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008787 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00008788#endif
8789#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008790 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008791#endif
8792#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008793 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008794#endif
8795#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00008796 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008797#endif
8798#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008799 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008800#endif
8801#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008802 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008803#endif
8804#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008805 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008806#endif
Fred Draked86ed291999-12-15 15:34:33 +00008807#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00008808 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00008809#endif
Fred Drakec9680921999-12-13 16:37:25 +00008810#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008811 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008812#endif
8813#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008814 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008815#endif
8816#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008817 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008818#endif
Fred Draked86ed291999-12-15 15:34:33 +00008819#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008820 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00008821#endif
Fred Drakec9680921999-12-13 16:37:25 +00008822#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00008823 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00008824#endif
Fred Draked86ed291999-12-15 15:34:33 +00008825#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00008826 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00008827#endif
8828#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00008829 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00008830#endif
Fred Drakec9680921999-12-13 16:37:25 +00008831#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008832 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008833#endif
8834#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008835 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008836#endif
8837#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008838 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008839#endif
8840#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008841 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008842#endif
Fred Draked86ed291999-12-15 15:34:33 +00008843#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00008844 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00008845#endif
Fred Drakec9680921999-12-13 16:37:25 +00008846#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00008847 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00008848#endif
8849#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00008850 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00008851#endif
8852#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008853 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008854#endif
8855#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008856 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00008857#endif
8858#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00008859 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00008860#endif
8861#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00008862 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00008863#endif
8864#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00008865 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00008866#endif
Fred Draked86ed291999-12-15 15:34:33 +00008867#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00008868 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00008869#endif
Fred Drakec9680921999-12-13 16:37:25 +00008870#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008871 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008872#endif
8873#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008874 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008875#endif
Fred Draked86ed291999-12-15 15:34:33 +00008876#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008877 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008878#endif
Fred Drakec9680921999-12-13 16:37:25 +00008879#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008880 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008881#endif
8882#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008883 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008884#endif
8885#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008886 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008887#endif
8888#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008889 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008890#endif
8891#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008892 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008893#endif
8894#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008895 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008896#endif
8897#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008898 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008899#endif
8900#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008901 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00008902#endif
8903#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00008904 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00008905#endif
Fred Draked86ed291999-12-15 15:34:33 +00008906#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008907 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00008908#endif
8909#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00008910 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00008911#endif
Fred Drakec9680921999-12-13 16:37:25 +00008912#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00008913 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00008914#endif
8915#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008916 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008917#endif
8918#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00008919 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008920#endif
8921#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00008922 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008923#endif
8924#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008925 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008926#endif
8927#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00008928 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008929#endif
8930#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00008931 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00008932#endif
8933#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00008934 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00008935#endif
8936#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00008937 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00008938#endif
8939#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00008940 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00008941#endif
8942#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00008943 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00008944#endif
8945#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008946 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00008947#endif
8948#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008949 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00008950#endif
8951#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00008952 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00008953#endif
8954#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00008955 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00008956#endif
8957#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00008958 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00008959#endif
8960#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00008961 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00008962#endif
8963#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008964 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008965#endif
8966#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00008967 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008968#endif
8969#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00008970 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00008971#endif
8972#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008973 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008974#endif
8975#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008976 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008977#endif
8978#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00008979 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00008980#endif
8981#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008982 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008983#endif
8984#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008985 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008986#endif
8987#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008988 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00008989#endif
8990#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00008991 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00008992#endif
8993#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008994 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008995#endif
8996#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008997 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008998#endif
8999#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009000 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00009001#endif
9002#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009003 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009004#endif
9005#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009006 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009007#endif
9008#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009009 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009010#endif
9011#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009012 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009013#endif
9014#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009015 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009016#endif
Fred Draked86ed291999-12-15 15:34:33 +00009017#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00009018 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00009019#endif
Fred Drakec9680921999-12-13 16:37:25 +00009020#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00009021 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00009022#endif
9023#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009024 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009025#endif
9026#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00009027 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00009028#endif
9029#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009030 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009031#endif
9032#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009033 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009034#endif
9035#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009036 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009037#endif
9038#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00009039 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00009040#endif
9041#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009042 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009043#endif
9044#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009045 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009046#endif
9047#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009048 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009049#endif
9050#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009051 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009052#endif
9053#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009054 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00009055#endif
9056#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009057 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00009058#endif
9059#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00009060 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00009061#endif
9062#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009063 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009064#endif
9065#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009066 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009067#endif
9068#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009069 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009070#endif
9071#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009072 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00009073#endif
9074#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009075 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009076#endif
9077#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009078 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009079#endif
9080#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009081 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009082#endif
9083#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009084 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009085#endif
9086#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009087 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009088#endif
9089#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009090 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009091#endif
9092#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00009093 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00009094#endif
9095#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009096 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009097#endif
9098#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009099 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009100#endif
9101#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009102 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009103#endif
9104#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009105 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009106#endif
9107#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00009108 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00009109#endif
9110#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009111 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009112#endif
9113#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00009114 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00009115#endif
9116#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009117 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009118#endif
9119#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00009120 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00009121#endif
9122#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00009123 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00009124#endif
9125#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00009126 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00009127#endif
9128#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00009129 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00009130#endif
9131#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009132 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009133#endif
9134#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00009135 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00009136#endif
9137#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00009138 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00009139#endif
9140#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009141 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009142#endif
9143#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009144 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009145#endif
9146#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00009147 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00009148#endif
9149#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00009150 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00009151#endif
9152#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00009153 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00009154#endif
9155};
9156
9157static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009158conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009159{
9160 return conv_confname(arg, valuep, posix_constants_sysconf,
9161 sizeof(posix_constants_sysconf)
9162 / sizeof(struct constdef));
9163}
9164
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009165PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009166"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009167Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009168
9169static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009170posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009171{
9172 PyObject *result = NULL;
9173 int name;
9174
9175 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
9176 int value;
9177
9178 errno = 0;
9179 value = sysconf(name);
9180 if (value == -1 && errno != 0)
9181 posix_error();
9182 else
Christian Heimes217cfd12007-12-02 14:31:20 +00009183 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00009184 }
9185 return result;
9186}
9187#endif
9188
9189
Fred Drakebec628d1999-12-15 18:31:10 +00009190/* This code is used to ensure that the tables of configuration value names
9191 * are in sorted order as required by conv_confname(), and also to build the
9192 * the exported dictionaries that are used to publish information about the
9193 * names available on the host platform.
9194 *
9195 * Sorting the table at runtime ensures that the table is properly ordered
9196 * when used, even for platforms we're not able to test on. It also makes
9197 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00009198 */
Fred Drakebec628d1999-12-15 18:31:10 +00009199
9200static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009201cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00009202{
9203 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009204 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00009205 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009206 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00009207
9208 return strcmp(c1->name, c2->name);
9209}
9210
9211static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009212setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00009213 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009214{
Fred Drakebec628d1999-12-15 18:31:10 +00009215 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00009216 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00009217
9218 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
9219 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00009220 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00009221 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009222
Barry Warsaw3155db32000-04-13 15:20:40 +00009223 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009224 PyObject *o = PyLong_FromLong(table[i].value);
9225 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
9226 Py_XDECREF(o);
9227 Py_DECREF(d);
9228 return -1;
9229 }
9230 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00009231 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00009232 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00009233}
9234
Fred Drakebec628d1999-12-15 18:31:10 +00009235/* Return -1 on failure, 0 on success. */
9236static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00009237setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009238{
9239#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00009240 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00009241 sizeof(posix_constants_pathconf)
9242 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009243 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009244 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009245#endif
9246#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00009247 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00009248 sizeof(posix_constants_confstr)
9249 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009250 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009251 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009252#endif
9253#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00009254 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00009255 sizeof(posix_constants_sysconf)
9256 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009257 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009258 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009259#endif
Fred Drakebec628d1999-12-15 18:31:10 +00009260 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00009261}
Fred Draked86ed291999-12-15 15:34:33 +00009262
9263
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009264PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009265"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009266Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009267in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009268
9269static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009270posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009271{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009272 abort();
9273 /*NOTREACHED*/
9274 Py_FatalError("abort() called from Python code didn't abort!");
9275 return NULL;
9276}
Fred Drakebec628d1999-12-15 18:31:10 +00009277
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00009278#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009279PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00009280"startfile(filepath [, operation]) - Start a file with its associated\n\
9281application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009282\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00009283When \"operation\" is not specified or \"open\", this acts like\n\
9284double-clicking the file in Explorer, or giving the file name as an\n\
9285argument to the DOS \"start\" command: the file is opened with whatever\n\
9286application (if any) its extension is associated.\n\
9287When another \"operation\" is given, it specifies what should be done with\n\
9288the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009289\n\
9290startfile returns as soon as the associated application is launched.\n\
9291There is no option to wait for the application to close, and no way\n\
9292to retrieve the application's exit status.\n\
9293\n\
9294The filepath is relative to the current directory. If you want to use\n\
9295an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009296the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00009297
9298static PyObject *
9299win32_startfile(PyObject *self, PyObject *args)
9300{
Victor Stinner8c62be82010-05-06 00:08:46 +00009301 PyObject *ofilepath;
9302 char *filepath;
9303 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02009304 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +00009305 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00009306
Victor Stinnereb5657a2011-09-30 01:44:27 +02009307 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009308 if (!PyArg_ParseTuple(args, "U|s:startfile",
9309 &unipath, &operation)) {
9310 PyErr_Clear();
9311 goto normal;
9312 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009313
Victor Stinner8c62be82010-05-06 00:08:46 +00009314 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009315 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +00009316 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +02009317 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009318 PyErr_Clear();
9319 operation = NULL;
9320 goto normal;
9321 }
9322 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009323
Victor Stinnereb5657a2011-09-30 01:44:27 +02009324 wpath = PyUnicode_AsUnicode(unipath);
9325 if (wpath == NULL)
9326 goto normal;
9327 if (uoperation) {
9328 woperation = PyUnicode_AsUnicode(uoperation);
9329 if (woperation == NULL)
9330 goto normal;
9331 }
9332 else
9333 woperation = NULL;
9334
Victor Stinner8c62be82010-05-06 00:08:46 +00009335 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02009336 rc = ShellExecuteW((HWND)0, woperation, wpath,
9337 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +00009338 Py_END_ALLOW_THREADS
9339
Victor Stinnereb5657a2011-09-30 01:44:27 +02009340 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +00009341 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009342 win32_error_object("startfile", unipath);
9343 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009344 }
9345 Py_INCREF(Py_None);
9346 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009347
9348normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00009349 if (!PyArg_ParseTuple(args, "O&|s:startfile",
9350 PyUnicode_FSConverter, &ofilepath,
9351 &operation))
9352 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01009353 if (win32_warn_bytes_api()) {
9354 Py_DECREF(ofilepath);
9355 return NULL;
9356 }
Victor Stinner8c62be82010-05-06 00:08:46 +00009357 filepath = PyBytes_AsString(ofilepath);
9358 Py_BEGIN_ALLOW_THREADS
9359 rc = ShellExecute((HWND)0, operation, filepath,
9360 NULL, NULL, SW_SHOWNORMAL);
9361 Py_END_ALLOW_THREADS
9362 if (rc <= (HINSTANCE)32) {
9363 PyObject *errval = win32_error("startfile", filepath);
9364 Py_DECREF(ofilepath);
9365 return errval;
9366 }
9367 Py_DECREF(ofilepath);
9368 Py_INCREF(Py_None);
9369 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00009370}
9371#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009372
Martin v. Löwis438b5342002-12-27 10:16:42 +00009373#ifdef HAVE_GETLOADAVG
9374PyDoc_STRVAR(posix_getloadavg__doc__,
9375"getloadavg() -> (float, float, float)\n\n\
9376Return the number of processes in the system run queue averaged over\n\
9377the last 1, 5, and 15 minutes or raises OSError if the load average\n\
9378was unobtainable");
9379
9380static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009381posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00009382{
9383 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00009384 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009385 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
9386 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00009387 } else
Stefan Krah0e803b32010-11-26 16:16:47 +00009388 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00009389}
9390#endif
9391
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009392PyDoc_STRVAR(device_encoding__doc__,
9393"device_encoding(fd) -> str\n\n\
9394Return a string describing the encoding of the device\n\
9395if the output is a terminal; else return None.");
9396
9397static PyObject *
9398device_encoding(PyObject *self, PyObject *args)
9399{
Victor Stinner8c62be82010-05-06 00:08:46 +00009400 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -05009401
Victor Stinner8c62be82010-05-06 00:08:46 +00009402 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
9403 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -05009404
9405 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009406}
9407
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009408#ifdef __VMS
9409/* Use openssl random routine */
9410#include <openssl/rand.h>
9411PyDoc_STRVAR(vms_urandom__doc__,
9412"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00009413Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009414
9415static PyObject*
9416vms_urandom(PyObject *self, PyObject *args)
9417{
Victor Stinner8c62be82010-05-06 00:08:46 +00009418 int howMany;
9419 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009420
Victor Stinner8c62be82010-05-06 00:08:46 +00009421 /* Read arguments */
9422 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
9423 return NULL;
9424 if (howMany < 0)
9425 return PyErr_Format(PyExc_ValueError,
9426 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009427
Victor Stinner8c62be82010-05-06 00:08:46 +00009428 /* Allocate bytes */
9429 result = PyBytes_FromStringAndSize(NULL, howMany);
9430 if (result != NULL) {
9431 /* Get random data */
9432 if (RAND_pseudo_bytes((unsigned char*)
9433 PyBytes_AS_STRING(result),
9434 howMany) < 0) {
9435 Py_DECREF(result);
9436 return PyErr_Format(PyExc_ValueError,
9437 "RAND_pseudo_bytes");
9438 }
9439 }
9440 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009441}
9442#endif
9443
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009444#ifdef HAVE_SETRESUID
9445PyDoc_STRVAR(posix_setresuid__doc__,
9446"setresuid(ruid, euid, suid)\n\n\
9447Set the current process's real, effective, and saved user ids.");
9448
9449static PyObject*
9450posix_setresuid (PyObject *self, PyObject *args)
9451{
Victor Stinner8c62be82010-05-06 00:08:46 +00009452 /* We assume uid_t is no larger than a long. */
9453 long ruid, euid, suid;
9454 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
9455 return NULL;
9456 if (setresuid(ruid, euid, suid) < 0)
9457 return posix_error();
9458 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009459}
9460#endif
9461
9462#ifdef HAVE_SETRESGID
9463PyDoc_STRVAR(posix_setresgid__doc__,
9464"setresgid(rgid, egid, sgid)\n\n\
9465Set the current process's real, effective, and saved group ids.");
9466
9467static PyObject*
9468posix_setresgid (PyObject *self, PyObject *args)
9469{
Victor Stinner8c62be82010-05-06 00:08:46 +00009470 /* We assume uid_t is no larger than a long. */
9471 long rgid, egid, sgid;
9472 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
9473 return NULL;
9474 if (setresgid(rgid, egid, sgid) < 0)
9475 return posix_error();
9476 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009477}
9478#endif
9479
9480#ifdef HAVE_GETRESUID
9481PyDoc_STRVAR(posix_getresuid__doc__,
9482"getresuid() -> (ruid, euid, suid)\n\n\
9483Get tuple of the current process's real, effective, and saved user ids.");
9484
9485static PyObject*
9486posix_getresuid (PyObject *self, PyObject *noargs)
9487{
Victor Stinner8c62be82010-05-06 00:08:46 +00009488 uid_t ruid, euid, suid;
9489 long l_ruid, l_euid, l_suid;
9490 if (getresuid(&ruid, &euid, &suid) < 0)
9491 return posix_error();
9492 /* Force the values into long's as we don't know the size of uid_t. */
9493 l_ruid = ruid;
9494 l_euid = euid;
9495 l_suid = suid;
9496 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009497}
9498#endif
9499
9500#ifdef HAVE_GETRESGID
9501PyDoc_STRVAR(posix_getresgid__doc__,
9502"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00009503Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009504
9505static PyObject*
9506posix_getresgid (PyObject *self, PyObject *noargs)
9507{
Victor Stinner8c62be82010-05-06 00:08:46 +00009508 uid_t rgid, egid, sgid;
9509 long l_rgid, l_egid, l_sgid;
9510 if (getresgid(&rgid, &egid, &sgid) < 0)
9511 return posix_error();
9512 /* Force the values into long's as we don't know the size of uid_t. */
9513 l_rgid = rgid;
9514 l_egid = egid;
9515 l_sgid = sgid;
9516 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009517}
9518#endif
9519
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009520/* Posix *at family of functions:
9521 faccessat, fchmodat, fchownat, fstatat, futimesat,
9522 linkat, mkdirat, mknodat, openat, readlinkat, renameat, symlinkat,
9523 unlinkat, utimensat, mkfifoat */
9524
9525#ifdef HAVE_FACCESSAT
9526PyDoc_STRVAR(posix_faccessat__doc__,
9527"faccessat(dirfd, path, mode, flags=0) -> True if granted, False otherwise\n\n\
9528Like access() but if path is relative, it is taken as relative to dirfd.\n\
9529flags is optional and can be constructed by ORing together zero or more\n\
9530of these values: AT_SYMLINK_NOFOLLOW, AT_EACCESS.\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 *
9535posix_faccessat(PyObject *self, PyObject *args)
9536{
9537 PyObject *opath;
9538 char *path;
9539 int mode;
9540 int res;
9541 int dirfd, flags = 0;
9542 if (!PyArg_ParseTuple(args, "iO&i|i:faccessat",
9543 &dirfd, PyUnicode_FSConverter, &opath, &mode, &flags))
9544 return NULL;
9545 path = PyBytes_AsString(opath);
9546 Py_BEGIN_ALLOW_THREADS
9547 res = faccessat(dirfd, path, mode, flags);
9548 Py_END_ALLOW_THREADS
9549 Py_DECREF(opath);
9550 return PyBool_FromLong(res == 0);
9551}
9552#endif
9553
9554#ifdef HAVE_FCHMODAT
9555PyDoc_STRVAR(posix_fchmodat__doc__,
9556"fchmodat(dirfd, path, mode, flags=0)\n\n\
9557Like chmod() but if path is relative, it is taken as relative to dirfd.\n\
9558flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9559If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9560is interpreted relative to the current working directory.");
9561
9562static PyObject *
9563posix_fchmodat(PyObject *self, PyObject *args)
9564{
9565 int dirfd, mode, res;
9566 int flags = 0;
9567 PyObject *opath;
9568 char *path;
9569
9570 if (!PyArg_ParseTuple(args, "iO&i|i:fchmodat",
9571 &dirfd, PyUnicode_FSConverter, &opath, &mode, &flags))
9572 return NULL;
9573
9574 path = PyBytes_AsString(opath);
9575
9576 Py_BEGIN_ALLOW_THREADS
9577 res = fchmodat(dirfd, path, mode, flags);
9578 Py_END_ALLOW_THREADS
9579 Py_DECREF(opath);
9580 if (res < 0)
9581 return posix_error();
9582 Py_RETURN_NONE;
9583}
9584#endif /* HAVE_FCHMODAT */
9585
9586#ifdef HAVE_FCHOWNAT
9587PyDoc_STRVAR(posix_fchownat__doc__,
9588"fchownat(dirfd, path, uid, gid, flags=0)\n\n\
9589Like chown() but if path is relative, it is taken as relative to dirfd.\n\
9590flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9591If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9592is interpreted relative to the current working directory.");
9593
9594static PyObject *
9595posix_fchownat(PyObject *self, PyObject *args)
9596{
9597 PyObject *opath;
9598 int dirfd, res;
9599 long uid, gid;
9600 int flags = 0;
9601 char *path;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009602
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009603 if (!PyArg_ParseTuple(args, "iO&ll|i:fchownat",
9604 &dirfd, PyUnicode_FSConverter, &opath, &uid, &gid, &flags))
9605 return NULL;
9606
9607 path = PyBytes_AsString(opath);
9608
9609 Py_BEGIN_ALLOW_THREADS
9610 res = fchownat(dirfd, path, (uid_t) uid, (gid_t) gid, flags);
9611 Py_END_ALLOW_THREADS
9612 Py_DECREF(opath);
9613 if (res < 0)
9614 return posix_error();
9615 Py_RETURN_NONE;
9616}
9617#endif /* HAVE_FCHOWNAT */
9618
9619#ifdef HAVE_FSTATAT
9620PyDoc_STRVAR(posix_fstatat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01009621"fstatat(dirfd, path, flags=0) -> stat result\n\n\
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009622Like stat() but if path is relative, it is taken as relative to dirfd.\n\
9623flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9624If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9625is interpreted relative to the current working directory.");
9626
9627static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01009628posix_fstatat(PyObject *self, PyObject *args)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009629{
9630 PyObject *opath;
9631 char *path;
9632 STRUCT_STAT st;
9633 int dirfd, res, flags = 0;
9634
Victor Stinner4195b5c2012-02-08 23:03:19 +01009635 if (!PyArg_ParseTuple(args, "iO&|i:fstatat",
9636 &dirfd, PyUnicode_FSConverter, &opath, &flags))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009637 return NULL;
9638 path = PyBytes_AsString(opath);
9639
9640 Py_BEGIN_ALLOW_THREADS
9641 res = fstatat(dirfd, path, &st, flags);
9642 Py_END_ALLOW_THREADS
9643 Py_DECREF(opath);
9644 if (res != 0)
9645 return posix_error();
9646
Victor Stinner4195b5c2012-02-08 23:03:19 +01009647 return _pystat_fromstructstat(&st);
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009648}
9649#endif
9650
9651#ifdef HAVE_FUTIMESAT
9652PyDoc_STRVAR(posix_futimesat__doc__,
Brian Curtin7ef53ef2011-11-07 14:38:24 -06009653"futimesat(dirfd, path[, (atime, mtime)])\n\
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009654Like utime() but if path is relative, it is taken as relative to dirfd.\n\
9655If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9656is interpreted relative to the current working directory.");
9657
9658static PyObject *
9659posix_futimesat(PyObject *self, PyObject *args)
9660{
9661 PyObject *opath;
9662 char *path;
9663 int res, dirfd;
Brian Curtin7ef53ef2011-11-07 14:38:24 -06009664 PyObject* arg = Py_None;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009665 time_t atime, mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01009666 long ansec, mnsec;
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009667
Brian Curtin7ef53ef2011-11-07 14:38:24 -06009668 if (!PyArg_ParseTuple(args, "iO&|O:futimesat",
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009669 &dirfd, PyUnicode_FSConverter, &opath, &arg))
9670 return NULL;
9671 path = PyBytes_AsString(opath);
9672 if (arg == Py_None) {
9673 /* optional time values not given */
9674 Py_BEGIN_ALLOW_THREADS
9675 res = futimesat(dirfd, path, NULL);
9676 Py_END_ALLOW_THREADS
9677 }
9678 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
9679 PyErr_SetString(PyExc_TypeError,
9680 "futimesat() arg 3 must be a tuple (atime, mtime)");
9681 Py_DECREF(opath);
9682 return NULL;
9683 }
9684 else {
Victor Stinner5d272cc2012-03-13 13:35:55 +01009685 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(arg, 0),
9686 &atime, &ansec) == -1) {
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009687 Py_DECREF(opath);
9688 return NULL;
9689 }
Victor Stinner5d272cc2012-03-13 13:35:55 +01009690 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(arg, 1),
9691 &mtime, &mnsec) == -1) {
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009692 Py_DECREF(opath);
9693 return NULL;
9694 }
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009695
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009696 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009697 {
9698#ifdef HAVE_UTIMENSAT
9699 struct timespec buf[2];
9700 buf[0].tv_sec = atime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01009701 buf[0].tv_nsec = ansec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009702 buf[1].tv_sec = mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01009703 buf[1].tv_nsec = mnsec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009704 res = utimensat(dirfd, path, buf, 0);
9705#else
9706 struct timeval buf[2];
9707 buf[0].tv_sec = atime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01009708 buf[0].tv_usec = ansec / 1000;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009709 buf[1].tv_sec = mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01009710 buf[1].tv_usec = mnsec / 1000;
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009711 res = futimesat(dirfd, path, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009712#endif
9713 }
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009714 Py_END_ALLOW_THREADS
9715 }
9716 Py_DECREF(opath);
9717 if (res < 0) {
9718 return posix_error();
9719 }
9720 Py_RETURN_NONE;
9721}
9722#endif
9723
9724#ifdef HAVE_LINKAT
9725PyDoc_STRVAR(posix_linkat__doc__,
9726"linkat(srcfd, srcpath, dstfd, dstpath, flags=0)\n\n\
9727Like link() but if srcpath is relative, it is taken as relative to srcfd\n\
9728and if dstpath is relative, it is taken as relative to dstfd.\n\
9729flags is optional and may be 0 or AT_SYMLINK_FOLLOW.\n\
9730If srcpath is relative and srcfd is the special value AT_FDCWD, then\n\
9731srcpath is interpreted relative to the current working directory. This\n\
9732also applies for dstpath.");
9733
9734static PyObject *
9735posix_linkat(PyObject *self, PyObject *args)
9736{
9737 PyObject *osrc, *odst;
9738 char *src, *dst;
9739 int res, srcfd, dstfd;
9740 int flags = 0;
9741
9742 if (!PyArg_ParseTuple(args, "iO&iO&|i:linkat",
9743 &srcfd, PyUnicode_FSConverter, &osrc, &dstfd, PyUnicode_FSConverter, &odst, &flags))
9744 return NULL;
9745 src = PyBytes_AsString(osrc);
9746 dst = PyBytes_AsString(odst);
9747 Py_BEGIN_ALLOW_THREADS
9748 res = linkat(srcfd, src, dstfd, dst, flags);
9749 Py_END_ALLOW_THREADS
9750 Py_DECREF(osrc);
9751 Py_DECREF(odst);
9752 if (res < 0)
9753 return posix_error();
9754 Py_RETURN_NONE;
9755}
9756#endif /* HAVE_LINKAT */
9757
9758#ifdef HAVE_MKDIRAT
9759PyDoc_STRVAR(posix_mkdirat__doc__,
9760"mkdirat(dirfd, path, mode=0o777)\n\n\
9761Like mkdir() but if path is relative, it is taken as relative to dirfd.\n\
9762If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9763is interpreted relative to the current working directory.");
9764
9765static PyObject *
9766posix_mkdirat(PyObject *self, PyObject *args)
9767{
9768 int res, dirfd;
9769 PyObject *opath;
9770 char *path;
9771 int mode = 0777;
9772
9773 if (!PyArg_ParseTuple(args, "iO&|i:mkdirat",
9774 &dirfd, PyUnicode_FSConverter, &opath, &mode))
9775 return NULL;
9776 path = PyBytes_AsString(opath);
9777 Py_BEGIN_ALLOW_THREADS
9778 res = mkdirat(dirfd, path, mode);
9779 Py_END_ALLOW_THREADS
9780 Py_DECREF(opath);
9781 if (res < 0)
9782 return posix_error();
9783 Py_RETURN_NONE;
9784}
9785#endif
9786
9787#if defined(HAVE_MKNODAT) && defined(HAVE_MAKEDEV)
9788PyDoc_STRVAR(posix_mknodat__doc__,
9789"mknodat(dirfd, path, mode=0o600, device=0)\n\n\
9790Like mknod() but if path is relative, it is taken as relative to dirfd.\n\
9791If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9792is interpreted relative to the current working directory.");
9793
9794static PyObject *
9795posix_mknodat(PyObject *self, PyObject *args)
9796{
9797 PyObject *opath;
9798 char *filename;
9799 int mode = 0600;
9800 int device = 0;
9801 int res, dirfd;
9802 if (!PyArg_ParseTuple(args, "iO&|ii:mknodat", &dirfd,
9803 PyUnicode_FSConverter, &opath, &mode, &device))
9804 return NULL;
9805 filename = PyBytes_AS_STRING(opath);
9806 Py_BEGIN_ALLOW_THREADS
9807 res = mknodat(dirfd, filename, mode, device);
9808 Py_END_ALLOW_THREADS
9809 Py_DECREF(opath);
9810 if (res < 0)
9811 return posix_error();
9812 Py_RETURN_NONE;
9813}
9814#endif
9815
9816#ifdef HAVE_OPENAT
9817PyDoc_STRVAR(posix_openat__doc__,
9818"openat(dirfd, path, flag, mode=0o777) -> fd\n\n\
9819Like open() but if path is relative, it is taken as relative to dirfd.\n\
9820If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9821is interpreted relative to the current working directory.");
9822
9823static PyObject *
9824posix_openat(PyObject *self, PyObject *args)
9825{
9826 PyObject *ofile;
9827 char *file;
9828 int flag, dirfd, fd;
9829 int mode = 0777;
9830
9831 if (!PyArg_ParseTuple(args, "iO&i|i:openat",
9832 &dirfd, PyUnicode_FSConverter, &ofile,
9833 &flag, &mode))
9834 return NULL;
9835 file = PyBytes_AsString(ofile);
9836 Py_BEGIN_ALLOW_THREADS
9837 fd = openat(dirfd, file, flag, mode);
9838 Py_END_ALLOW_THREADS
9839 Py_DECREF(ofile);
9840 if (fd < 0)
9841 return posix_error();
9842 return PyLong_FromLong((long)fd);
9843}
9844#endif
9845
9846#ifdef HAVE_READLINKAT
9847PyDoc_STRVAR(posix_readlinkat__doc__,
9848"readlinkat(dirfd, path) -> path\n\n\
9849Like readlink() but if path is relative, it is taken as relative to dirfd.\n\
9850If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9851is interpreted relative to the current working directory.");
9852
9853static PyObject *
9854posix_readlinkat(PyObject *self, PyObject *args)
9855{
9856 PyObject *v, *opath;
9857 char buf[MAXPATHLEN];
9858 char *path;
9859 int n, dirfd;
9860 int arg_is_unicode = 0;
9861
9862 if (!PyArg_ParseTuple(args, "iO&:readlinkat",
9863 &dirfd, PyUnicode_FSConverter, &opath))
9864 return NULL;
9865 path = PyBytes_AsString(opath);
9866 v = PySequence_GetItem(args, 1);
9867 if (v == NULL) {
9868 Py_DECREF(opath);
9869 return NULL;
9870 }
9871
9872 if (PyUnicode_Check(v)) {
9873 arg_is_unicode = 1;
9874 }
9875 Py_DECREF(v);
9876
9877 Py_BEGIN_ALLOW_THREADS
9878 n = readlinkat(dirfd, path, buf, (int) sizeof buf);
9879 Py_END_ALLOW_THREADS
9880 Py_DECREF(opath);
9881 if (n < 0)
9882 return posix_error();
9883
9884 if (arg_is_unicode)
9885 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
9886 else
9887 return PyBytes_FromStringAndSize(buf, n);
9888}
9889#endif /* HAVE_READLINKAT */
9890
9891#ifdef HAVE_RENAMEAT
9892PyDoc_STRVAR(posix_renameat__doc__,
9893"renameat(olddirfd, oldpath, newdirfd, newpath)\n\n\
9894Like rename() but if oldpath is relative, it is taken as relative to\n\
9895olddirfd and if newpath is relative, it is taken as relative to newdirfd.\n\
9896If oldpath is relative and olddirfd is the special value AT_FDCWD, then\n\
9897oldpath is interpreted relative to the current working directory. This\n\
9898also applies for newpath.");
9899
9900static PyObject *
9901posix_renameat(PyObject *self, PyObject *args)
9902{
9903 int res;
9904 PyObject *opathold, *opathnew;
9905 char *opath, *npath;
9906 int oldfd, newfd;
9907
9908 if (!PyArg_ParseTuple(args, "iO&iO&:renameat",
9909 &oldfd, PyUnicode_FSConverter, &opathold, &newfd, PyUnicode_FSConverter, &opathnew))
9910 return NULL;
9911 opath = PyBytes_AsString(opathold);
9912 npath = PyBytes_AsString(opathnew);
9913 Py_BEGIN_ALLOW_THREADS
9914 res = renameat(oldfd, opath, newfd, npath);
9915 Py_END_ALLOW_THREADS
9916 Py_DECREF(opathold);
9917 Py_DECREF(opathnew);
9918 if (res < 0)
9919 return posix_error();
9920 Py_RETURN_NONE;
9921}
9922#endif
9923
9924#if HAVE_SYMLINKAT
9925PyDoc_STRVAR(posix_symlinkat__doc__,
9926"symlinkat(src, dstfd, dst)\n\n\
9927Like symlink() but if dst is relative, it is taken as relative to dstfd.\n\
9928If dst is relative and dstfd is the special value AT_FDCWD, then dst\n\
9929is interpreted relative to the current working directory.");
9930
9931static PyObject *
9932posix_symlinkat(PyObject *self, PyObject *args)
9933{
9934 int res, dstfd;
9935 PyObject *osrc, *odst;
9936 char *src, *dst;
9937
9938 if (!PyArg_ParseTuple(args, "O&iO&:symlinkat",
9939 PyUnicode_FSConverter, &osrc, &dstfd, PyUnicode_FSConverter, &odst))
9940 return NULL;
9941 src = PyBytes_AsString(osrc);
9942 dst = PyBytes_AsString(odst);
9943 Py_BEGIN_ALLOW_THREADS
9944 res = symlinkat(src, dstfd, dst);
9945 Py_END_ALLOW_THREADS
9946 Py_DECREF(osrc);
9947 Py_DECREF(odst);
9948 if (res < 0)
9949 return posix_error();
9950 Py_RETURN_NONE;
9951}
9952#endif /* HAVE_SYMLINKAT */
9953
9954#ifdef HAVE_UNLINKAT
9955PyDoc_STRVAR(posix_unlinkat__doc__,
9956"unlinkat(dirfd, path, flags=0)\n\n\
9957Like unlink() but if path is relative, it is taken as relative to dirfd.\n\
9958flags is optional and may be 0 or AT_REMOVEDIR. If AT_REMOVEDIR is\n\
9959specified, unlinkat() behaves like rmdir().\n\
9960If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9961is interpreted relative to the current working directory.");
9962
9963static PyObject *
9964posix_unlinkat(PyObject *self, PyObject *args)
9965{
9966 int dirfd, res, flags = 0;
9967 PyObject *opath;
9968 char *path;
9969
9970 if (!PyArg_ParseTuple(args, "iO&|i:unlinkat",
9971 &dirfd, PyUnicode_FSConverter, &opath, &flags))
9972 return NULL;
9973 path = PyBytes_AsString(opath);
9974 Py_BEGIN_ALLOW_THREADS
9975 res = unlinkat(dirfd, path, flags);
9976 Py_END_ALLOW_THREADS
9977 Py_DECREF(opath);
9978 if (res < 0)
9979 return posix_error();
9980 Py_RETURN_NONE;
9981}
9982#endif
9983
9984#ifdef HAVE_UTIMENSAT
9985PyDoc_STRVAR(posix_utimensat__doc__,
Brian Curtin569b4942011-11-07 16:09:20 -06009986"utimensat(dirfd, path[, atime=(atime_sec, atime_nsec),\n\
9987 mtime=(mtime_sec, mtime_nsec), flags=0])\n\
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009988utimensat(dirfd, path, None, None, flags)\n\n\
9989Updates the timestamps of a file with nanosecond precision. If path is\n\
9990relative, it is taken as relative to dirfd.\n\
Brian Curtin569b4942011-11-07 16:09:20 -06009991If atime and mtime are both None, which is the default, set atime and\n\
9992mtime to the current time.\n\
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009993flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9994If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9995is interpreted relative to the current working directory.\n\
9996If *_nsec is specified as UTIME_NOW, the timestamp is updated to the\n\
9997current time.\n\
9998If *_nsec is specified as UTIME_OMIT, the timestamp is not updated.");
9999
10000static PyObject *
Brian Curtin569b4942011-11-07 16:09:20 -060010001posix_utimensat(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010002{
10003 PyObject *opath;
10004 char *path;
10005 int res, dirfd, flags = 0;
Brian Curtin569b4942011-11-07 16:09:20 -060010006 PyObject *atime = Py_None;
10007 PyObject *mtime = Py_None;
10008
10009 static char *kwlist[] = {"dirfd", "path", "atime", "mtime", "flags", NULL};
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010010
10011 struct timespec buf[2];
10012
Brian Curtin569b4942011-11-07 16:09:20 -060010013 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iO&|OOi:utimensat", kwlist,
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010014 &dirfd, PyUnicode_FSConverter, &opath, &atime, &mtime, &flags))
10015 return NULL;
10016 path = PyBytes_AsString(opath);
10017 if (atime == Py_None && mtime == Py_None) {
10018 /* optional time values not given */
10019 Py_BEGIN_ALLOW_THREADS
10020 res = utimensat(dirfd, path, NULL, flags);
10021 Py_END_ALLOW_THREADS
10022 }
10023 else if (!PyTuple_Check(atime) || PyTuple_Size(atime) != 2) {
10024 PyErr_SetString(PyExc_TypeError,
10025 "utimensat() arg 3 must be a tuple (atime_sec, atime_nsec)");
10026 Py_DECREF(opath);
10027 return NULL;
10028 }
10029 else if (!PyTuple_Check(mtime) || PyTuple_Size(mtime) != 2) {
10030 PyErr_SetString(PyExc_TypeError,
10031 "utimensat() arg 4 must be a tuple (mtime_sec, mtime_nsec)");
10032 Py_DECREF(opath);
10033 return NULL;
10034 }
10035 else {
10036 if (!PyArg_ParseTuple(atime, "ll:utimensat",
10037 &(buf[0].tv_sec), &(buf[0].tv_nsec))) {
10038 Py_DECREF(opath);
10039 return NULL;
10040 }
10041 if (!PyArg_ParseTuple(mtime, "ll:utimensat",
10042 &(buf[1].tv_sec), &(buf[1].tv_nsec))) {
10043 Py_DECREF(opath);
10044 return NULL;
10045 }
10046 Py_BEGIN_ALLOW_THREADS
10047 res = utimensat(dirfd, path, buf, flags);
10048 Py_END_ALLOW_THREADS
10049 }
10050 Py_DECREF(opath);
10051 if (res < 0) {
10052 return posix_error();
10053 }
10054 Py_RETURN_NONE;
10055}
10056#endif
10057
10058#ifdef HAVE_MKFIFOAT
10059PyDoc_STRVAR(posix_mkfifoat__doc__,
10060"mkfifoat(dirfd, path, mode=0o666)\n\n\
10061Like mkfifo() but if path is relative, it is taken as relative to dirfd.\n\
10062If path is relative and dirfd is the special value AT_FDCWD, then path\n\
10063is interpreted relative to the current working directory.");
10064
10065static PyObject *
10066posix_mkfifoat(PyObject *self, PyObject *args)
10067{
10068 PyObject *opath;
10069 char *filename;
10070 int mode = 0666;
10071 int res, dirfd;
10072 if (!PyArg_ParseTuple(args, "iO&|i:mkfifoat",
10073 &dirfd, PyUnicode_FSConverter, &opath, &mode))
10074 return NULL;
10075 filename = PyBytes_AS_STRING(opath);
10076 Py_BEGIN_ALLOW_THREADS
10077 res = mkfifoat(dirfd, filename, mode);
10078 Py_END_ALLOW_THREADS
10079 Py_DECREF(opath);
10080 if (res < 0)
10081 return posix_error();
10082 Py_RETURN_NONE;
10083}
10084#endif
10085
Benjamin Peterson9428d532011-09-14 11:45:52 -040010086#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010087
10088static int
10089try_getxattr(const char *path, const char *name,
10090 ssize_t (*get)(const char *, const char *, void *, size_t),
10091 Py_ssize_t buf_size, PyObject **res)
10092{
10093 PyObject *value;
10094 Py_ssize_t len;
10095
10096 assert(buf_size <= XATTR_SIZE_MAX);
10097 value = PyBytes_FromStringAndSize(NULL, buf_size);
10098 if (!value)
10099 return 0;
10100 Py_BEGIN_ALLOW_THREADS;
10101 len = get(path, name, PyBytes_AS_STRING(value), buf_size);
10102 Py_END_ALLOW_THREADS;
10103 if (len < 0) {
10104 Py_DECREF(value);
10105 if (errno == ERANGE) {
10106 value = NULL;
10107 }
10108 else {
10109 posix_error();
10110 return 0;
10111 }
10112 }
10113 else if (len != buf_size) {
10114 /* Can only shrink. */
10115 _PyBytes_Resize(&value, len);
10116 }
10117 *res = value;
10118 return 1;
10119}
10120
10121static PyObject *
10122getxattr_common(const char *path, PyObject *name_obj,
10123 ssize_t (*get)(const char *, const char *, void *, size_t))
10124{
10125 PyObject *value;
10126 const char *name = PyBytes_AS_STRING(name_obj);
10127
10128 /* Try a small value first. */
10129 if (!try_getxattr(path, name, get, 128, &value))
10130 return NULL;
10131 if (value)
10132 return value;
10133 /* Now the maximum possible one. */
10134 if (!try_getxattr(path, name, get, XATTR_SIZE_MAX, &value))
10135 return NULL;
10136 assert(value);
10137 return value;
10138}
10139
10140PyDoc_STRVAR(posix_getxattr__doc__,
10141"getxattr(path, attr) -> value\n\n\
10142Return the value of extended attribute *name* on *path*.");
10143
10144static PyObject *
10145posix_getxattr(PyObject *self, PyObject *args)
10146{
10147 PyObject *path, *res, *name;
10148
10149 if (!PyArg_ParseTuple(args, "O&O&:getxattr", PyUnicode_FSConverter, &path,
10150 PyUnicode_FSConverter, &name))
10151 return NULL;
10152 res = getxattr_common(PyBytes_AS_STRING(path), name, getxattr);
10153 Py_DECREF(path);
10154 Py_DECREF(name);
10155 return res;
10156}
10157
10158PyDoc_STRVAR(posix_lgetxattr__doc__,
10159"lgetxattr(path, attr) -> value\n\n\
10160Like getxattr but don't follow symlinks.");
10161
10162static PyObject *
10163posix_lgetxattr(PyObject *self, PyObject *args)
10164{
10165 PyObject *path, *res, *name;
10166
10167 if (!PyArg_ParseTuple(args, "O&O&:lgetxattr", PyUnicode_FSConverter, &path,
10168 PyUnicode_FSConverter, &name))
10169 return NULL;
10170 res = getxattr_common(PyBytes_AS_STRING(path), name, lgetxattr);
10171 Py_DECREF(path);
10172 Py_DECREF(name);
10173 return res;
10174}
10175
10176static ssize_t
10177wrap_fgetxattr(const char *path, const char *name, void *value, size_t size)
10178{
10179 /* Hack to share code. */
10180 return fgetxattr((int)(Py_uintptr_t)path, name, value, size);
10181}
10182
10183PyDoc_STRVAR(posix_fgetxattr__doc__,
10184"fgetxattr(fd, attr) -> value\n\n\
10185Like getxattr but operate on a fd instead of a path.");
10186
10187static PyObject *
10188posix_fgetxattr(PyObject *self, PyObject *args)
10189{
10190 PyObject *res, *name;
10191 int fd;
10192
10193 if (!PyArg_ParseTuple(args, "iO&:fgetxattr", &fd, PyUnicode_FSConverter, &name))
10194 return NULL;
10195 res = getxattr_common((const char *)(Py_uintptr_t)fd, name, wrap_fgetxattr);
10196 Py_DECREF(name);
10197 return res;
10198}
10199
10200PyDoc_STRVAR(posix_setxattr__doc__,
10201"setxattr(path, attr, value, flags=0)\n\n\
10202Set extended attribute *attr* on *path* to *value*.");
10203
10204static PyObject *
10205posix_setxattr(PyObject *self, PyObject *args)
10206{
10207 PyObject *path, *name;
10208 Py_buffer data;
10209 int flags = 0, err;
10210
10211 if (!PyArg_ParseTuple(args, "O&O&y*|i:setxattr", PyUnicode_FSConverter,
10212 &path, PyUnicode_FSConverter, &name, &data, &flags))
10213 return NULL;
10214 Py_BEGIN_ALLOW_THREADS;
10215 err = setxattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name),
10216 data.buf, data.len, flags);
10217 Py_END_ALLOW_THREADS;
10218 Py_DECREF(path);
10219 Py_DECREF(name);
10220 PyBuffer_Release(&data);
10221 if (err)
10222 return posix_error();
10223 Py_RETURN_NONE;
10224}
10225
10226PyDoc_STRVAR(posix_lsetxattr__doc__,
10227"lsetxattr(path, attr, value, flags=0)\n\n\
10228Like setxattr but don't follow symlinks.");
10229
10230static PyObject *
10231posix_lsetxattr(PyObject *self, PyObject *args)
10232{
10233 PyObject *path, *name;
10234 Py_buffer data;
10235 int flags = 0, err;
10236
10237 if (!PyArg_ParseTuple(args, "O&O&y*|i:lsetxattr", PyUnicode_FSConverter,
10238 &path, PyUnicode_FSConverter, &name, &data, &flags))
10239 return NULL;
10240 Py_BEGIN_ALLOW_THREADS;
10241 err = lsetxattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name),
10242 data.buf, data.len, flags);
10243 Py_END_ALLOW_THREADS;
10244 Py_DECREF(path);
10245 Py_DECREF(name);
10246 PyBuffer_Release(&data);
10247 if (err)
10248 return posix_error();
10249 Py_RETURN_NONE;
10250}
10251
10252PyDoc_STRVAR(posix_fsetxattr__doc__,
10253"fsetxattr(fd, attr, value, flags=0)\n\n\
10254Like setxattr but operates on *fd* instead of a path.");
10255
10256static PyObject *
10257posix_fsetxattr(PyObject *self, PyObject *args)
10258{
10259 Py_buffer data;
10260 const char *name;
10261 int fd, flags = 0, err;
10262
10263 if (!PyArg_ParseTuple(args, "iO&y*|i:fsetxattr", &fd, PyUnicode_FSConverter,
10264 &name, &data, &flags))
10265 return NULL;
10266 Py_BEGIN_ALLOW_THREADS;
10267 err = fsetxattr(fd, PyBytes_AS_STRING(name), data.buf, data.len, flags);
10268 Py_END_ALLOW_THREADS;
10269 Py_DECREF(name);
10270 PyBuffer_Release(&data);
10271 if (err)
10272 return posix_error();
10273 Py_RETURN_NONE;
10274}
10275
10276PyDoc_STRVAR(posix_removexattr__doc__,
10277"removexattr(path, attr)\n\n\
10278Remove extended attribute *attr* on *path*.");
10279
10280static PyObject *
10281posix_removexattr(PyObject *self, PyObject *args)
10282{
10283 PyObject *path, *name;
10284 int err;
10285
10286 if (!PyArg_ParseTuple(args, "O&O&:removexattr", PyUnicode_FSConverter, &path,
10287 PyUnicode_FSConverter, &name))
10288 return NULL;
10289 Py_BEGIN_ALLOW_THREADS;
10290 err = removexattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name));
10291 Py_END_ALLOW_THREADS;
10292 Py_DECREF(path);
10293 Py_DECREF(name);
10294 if (err)
10295 return posix_error();
10296 Py_RETURN_NONE;
10297}
10298
10299PyDoc_STRVAR(posix_lremovexattr__doc__,
10300"lremovexattr(path, attr)\n\n\
10301Like removexattr but don't follow symlinks.");
10302
10303static PyObject *
10304posix_lremovexattr(PyObject *self, PyObject *args)
10305{
10306 PyObject *path, *name;
10307 int err;
10308
10309 if (!PyArg_ParseTuple(args, "O&O&:lremovexattr", PyUnicode_FSConverter, &path,
10310 PyUnicode_FSConverter, &name))
10311 return NULL;
10312 Py_BEGIN_ALLOW_THREADS;
10313 err = lremovexattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name));
10314 Py_END_ALLOW_THREADS;
10315 Py_DECREF(path);
10316 Py_DECREF(name);
10317 if (err)
10318 return posix_error();
10319 Py_RETURN_NONE;
10320}
10321
10322PyDoc_STRVAR(posix_fremovexattr__doc__,
10323"fremovexattr(fd, attr)\n\n\
10324Like removexattr but operates on a file descriptor.");
10325
10326static PyObject *
10327posix_fremovexattr(PyObject *self, PyObject *args)
10328{
10329 PyObject *name;
10330 int fd, err;
10331
10332 if (!PyArg_ParseTuple(args, "iO&:fremovexattr", &fd,
10333 PyUnicode_FSConverter, &name))
10334 return NULL;
10335 Py_BEGIN_ALLOW_THREADS;
10336 err = fremovexattr(fd, PyBytes_AS_STRING(name));
10337 Py_END_ALLOW_THREADS;
10338 Py_DECREF(name);
10339 if (err)
10340 return posix_error();
10341 Py_RETURN_NONE;
10342}
10343
10344static Py_ssize_t
10345try_listxattr(const char *path, ssize_t (*list)(const char *, char *, size_t),
10346 Py_ssize_t buf_size, char **buf)
10347{
10348 Py_ssize_t len;
10349
10350 *buf = PyMem_MALLOC(buf_size);
10351 if (!*buf) {
10352 PyErr_NoMemory();
10353 return -1;
10354 }
10355 Py_BEGIN_ALLOW_THREADS;
10356 len = list(path, *buf, buf_size);
10357 Py_END_ALLOW_THREADS;
10358 if (len < 0) {
10359 PyMem_FREE(*buf);
10360 if (errno != ERANGE)
10361 posix_error();
10362 return -1;
10363 }
10364 return len;
10365}
10366
10367static PyObject *
10368listxattr_common(const char *path, ssize_t (*list)(const char *, char *, size_t))
10369{
10370 PyObject *res, *attr;
10371 Py_ssize_t len, err, start, i;
10372 char *buf;
10373
10374 len = try_listxattr(path, list, 256, &buf);
10375 if (len < 0) {
10376 if (PyErr_Occurred())
10377 return NULL;
10378 len = try_listxattr(path, list, XATTR_LIST_MAX, &buf);
10379 if (len < 0)
10380 return NULL;
10381 }
10382 res = PyList_New(0);
10383 if (!res) {
10384 PyMem_FREE(buf);
10385 return NULL;
10386 }
10387 for (start = i = 0; i < len; i++) {
10388 if (!buf[i]) {
10389 attr = PyUnicode_DecodeFSDefaultAndSize(&buf[start], i - start);
10390 if (!attr) {
10391 Py_DECREF(res);
10392 PyMem_FREE(buf);
10393 return NULL;
10394 }
10395 err = PyList_Append(res, attr);
10396 Py_DECREF(attr);
10397 if (err) {
10398 Py_DECREF(res);
10399 PyMem_FREE(buf);
10400 return NULL;
10401 }
10402 start = i + 1;
10403 }
10404 }
10405 PyMem_FREE(buf);
10406 return res;
10407}
10408
10409PyDoc_STRVAR(posix_listxattr__doc__,
10410"listxattr(path)\n\n\
10411Return a list of extended attributes on *path*.");
10412
10413static PyObject *
10414posix_listxattr(PyObject *self, PyObject *args)
10415{
10416 PyObject *path, *res;
10417
10418 if (!PyArg_ParseTuple(args, "O&:listxattr", PyUnicode_FSConverter, &path))
10419 return NULL;
10420 res = listxattr_common(PyBytes_AS_STRING(path), listxattr);
10421 Py_DECREF(path);
10422 return res;
10423}
10424
10425PyDoc_STRVAR(posix_llistxattr__doc__,
10426"llistxattr(path)\n\n\
10427Like listxattr but don't follow symlinks..");
10428
10429static PyObject *
10430posix_llistxattr(PyObject *self, PyObject *args)
10431{
10432 PyObject *path, *res;
10433
10434 if (!PyArg_ParseTuple(args, "O&:llistxattr", PyUnicode_FSConverter, &path))
10435 return NULL;
10436 res = listxattr_common(PyBytes_AS_STRING(path), llistxattr);
10437 Py_DECREF(path);
10438 return res;
10439}
10440
10441static ssize_t
10442wrap_flistxattr(const char *path, char *buf, size_t len)
10443{
10444 /* Hack to share code. */
10445 return flistxattr((int)(Py_uintptr_t)path, buf, len);
10446}
10447
10448PyDoc_STRVAR(posix_flistxattr__doc__,
10449"flistxattr(path)\n\n\
10450Like flistxattr but operates on a file descriptor.");
10451
10452static PyObject *
10453posix_flistxattr(PyObject *self, PyObject *args)
10454{
10455 long fd;
10456
10457 if (!PyArg_ParseTuple(args, "i:flistxattr", &fd))
10458 return NULL;
10459 return listxattr_common((const char *)(Py_uintptr_t)fd, wrap_flistxattr);
10460}
10461
Benjamin Peterson9428d532011-09-14 11:45:52 -040010462#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010463
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010464
Georg Brandl2fb477c2012-02-21 00:33:36 +010010465PyDoc_STRVAR(posix_urandom__doc__,
10466"urandom(n) -> str\n\n\
10467Return n random bytes suitable for cryptographic use.");
10468
10469static PyObject *
10470posix_urandom(PyObject *self, PyObject *args)
10471{
10472 Py_ssize_t size;
10473 PyObject *result;
10474 int ret;
10475
10476 /* Read arguments */
10477 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10478 return NULL;
10479 if (size < 0)
10480 return PyErr_Format(PyExc_ValueError,
10481 "negative argument not allowed");
10482 result = PyBytes_FromStringAndSize(NULL, size);
10483 if (result == NULL)
10484 return NULL;
10485
10486 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10487 PyBytes_GET_SIZE(result));
10488 if (ret == -1) {
10489 Py_DECREF(result);
10490 return NULL;
10491 }
10492 return result;
10493}
10494
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010495/* Terminal size querying */
10496
10497static PyTypeObject TerminalSizeType;
10498
10499PyDoc_STRVAR(TerminalSize_docstring,
10500 "A tuple of (columns, lines) for holding terminal window size");
10501
10502static PyStructSequence_Field TerminalSize_fields[] = {
10503 {"columns", "width of the terminal window in characters"},
10504 {"lines", "height of the terminal window in characters"},
10505 {NULL, NULL}
10506};
10507
10508static PyStructSequence_Desc TerminalSize_desc = {
10509 "os.terminal_size",
10510 TerminalSize_docstring,
10511 TerminalSize_fields,
10512 2,
10513};
10514
10515#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10516PyDoc_STRVAR(termsize__doc__,
10517 "Return the size of the terminal window as (columns, lines).\n" \
10518 "\n" \
10519 "The optional argument fd (default standard output) specifies\n" \
10520 "which file descriptor should be queried.\n" \
10521 "\n" \
10522 "If the file descriptor is not connected to a terminal, an OSError\n" \
10523 "is thrown.\n" \
10524 "\n" \
10525 "This function will only be defined if an implementation is\n" \
10526 "available for this system.\n" \
10527 "\n" \
10528 "shutil.get_terminal_size is the high-level function which should \n" \
10529 "normally be used, os.get_terminal_size is the low-level implementation.");
10530
10531static PyObject*
10532get_terminal_size(PyObject *self, PyObject *args)
10533{
10534 int columns, lines;
10535 PyObject *termsize;
10536
10537 int fd = fileno(stdout);
10538 /* Under some conditions stdout may not be connected and
10539 * fileno(stdout) may point to an invalid file descriptor. For example
10540 * GUI apps don't have valid standard streams by default.
10541 *
10542 * If this happens, and the optional fd argument is not present,
10543 * the ioctl below will fail returning EBADF. This is what we want.
10544 */
10545
10546 if (!PyArg_ParseTuple(args, "|i", &fd))
10547 return NULL;
10548
10549#ifdef TERMSIZE_USE_IOCTL
10550 {
10551 struct winsize w;
10552 if (ioctl(fd, TIOCGWINSZ, &w))
10553 return PyErr_SetFromErrno(PyExc_OSError);
10554 columns = w.ws_col;
10555 lines = w.ws_row;
10556 }
10557#endif /* TERMSIZE_USE_IOCTL */
10558
10559#ifdef TERMSIZE_USE_CONIO
10560 {
10561 DWORD nhandle;
10562 HANDLE handle;
10563 CONSOLE_SCREEN_BUFFER_INFO csbi;
10564 switch (fd) {
10565 case 0: nhandle = STD_INPUT_HANDLE;
10566 break;
10567 case 1: nhandle = STD_OUTPUT_HANDLE;
10568 break;
10569 case 2: nhandle = STD_ERROR_HANDLE;
10570 break;
10571 default:
10572 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10573 }
10574 handle = GetStdHandle(nhandle);
10575 if (handle == NULL)
10576 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10577 if (handle == INVALID_HANDLE_VALUE)
10578 return PyErr_SetFromWindowsErr(0);
10579
10580 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10581 return PyErr_SetFromWindowsErr(0);
10582
10583 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10584 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10585 }
10586#endif /* TERMSIZE_USE_CONIO */
10587
10588 termsize = PyStructSequence_New(&TerminalSizeType);
10589 if (termsize == NULL)
10590 return NULL;
10591 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10592 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10593 if (PyErr_Occurred()) {
10594 Py_DECREF(termsize);
10595 return NULL;
10596 }
10597 return termsize;
10598}
10599#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10600
10601
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010602static PyMethodDef posix_methods[] = {
Benjamin Petersoneaa5eee2012-05-05 21:22:14 -040010603 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010604#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010605 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010606#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010607 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010608#ifdef HAVE_CHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010609 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010610#endif /* HAVE_CHFLAGS */
Victor Stinner8c62be82010-05-06 00:08:46 +000010611 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010612#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010613 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010614#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010615#ifdef HAVE_CHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010616 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010617#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010618#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010619 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010620#endif /* HAVE_LCHMOD */
10621#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010622 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010623#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010624#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010625 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010626#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010627#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010628 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010629#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010630#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010631 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010632#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010633#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010634 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010635#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010636#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010637 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10638 METH_NOARGS, posix_getcwd__doc__},
10639 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10640 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010641#endif
10642#ifdef HAVE_LINK
Victor Stinner8c62be82010-05-06 00:08:46 +000010643 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010644#endif /* HAVE_LINK */
Victor Stinner8c62be82010-05-06 00:08:46 +000010645 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
Antoine Pitrou8250e232011-02-25 23:41:16 +000010646#ifdef HAVE_FDOPENDIR
Charles-François Natali77940902012-02-06 19:54:48 +010010647 {"flistdir", posix_flistdir, METH_VARARGS, posix_flistdir__doc__},
Antoine Pitrou8250e232011-02-25 23:41:16 +000010648#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010010649 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010650 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010651#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010652 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000010653#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010654#ifdef HAVE_GETPRIORITY
10655 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10656#endif /* HAVE_GETPRIORITY */
10657#ifdef HAVE_SETPRIORITY
10658 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10659#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010660#ifdef HAVE_READLINK
Victor Stinner8c62be82010-05-06 00:08:46 +000010661 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010662#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010663#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +000010664 {"readlink", win_readlink, METH_VARARGS, win_readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010665#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +000010666 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
Antoine Pitrouf3b2d882012-01-30 22:08:52 +010010667 {"replace", posix_replace, METH_VARARGS, posix_replace__doc__},
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +000010668 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
Victor Stinner4195b5c2012-02-08 23:03:19 +010010669 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010670 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Brian Curtin52173d42010-12-02 18:29:18 +000010671#if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +000010672 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010673#endif /* HAVE_SYMLINK */
Brian Curtin52173d42010-12-02 18:29:18 +000010674#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000010675 {"symlink", (PyCFunction)win_symlink, METH_VARARGS | METH_KEYWORDS,
Brian Curtin52173d42010-12-02 18:29:18 +000010676 win_symlink__doc__},
10677#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossum85e3b011991-06-03 12:42:10 +000010678#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010679 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010680#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010681 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010682#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010683 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010684#endif /* HAVE_UNAME */
Victor Stinner8c62be82010-05-06 00:08:46 +000010685 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
10686 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070010687 {"utime", (PyCFunction)posix_utime,
10688 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010689#ifdef HAVE_FUTIMES
Larry Hastings76ad59b2012-05-03 00:30:07 -070010690 {"futimes", (PyCFunction)posix_futimes,
10691 METH_VARARGS | METH_KEYWORDS, posix_futimes__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010692#endif
10693#ifdef HAVE_LUTIMES
Larry Hastings76ad59b2012-05-03 00:30:07 -070010694 {"lutimes", (PyCFunction)posix_lutimes,
10695 METH_VARARGS | METH_KEYWORDS, posix_lutimes__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010696#endif
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000010697#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010698 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010699#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010700 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010701#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010702 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
10703 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010704#endif /* HAVE_EXECV */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010705#ifdef HAVE_FEXECVE
10706 {"fexecve", posix_fexecve, METH_VARARGS, posix_fexecve__doc__},
10707#endif
Guido van Rossuma1065681999-01-25 23:20:23 +000010708#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010709 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10710 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010711#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000010712 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
10713 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010714#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +000010715#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010716#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010717 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010718#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010719#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010720 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010721#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010722#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010723#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010724 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
10725 {"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 +020010726#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010727#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010728 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010729#endif
10730#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010731 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010732#endif
10733#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010734 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010735#endif
10736#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010737 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010738#endif
10739#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010740 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010741#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010742 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050010743#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010744 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
10745 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
10746#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010747#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010748#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000010749 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010750#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000010751#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010752 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000010753#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000010754#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010755 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000010756#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010757#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010758 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000010759#endif /* HAVE_GETEUID */
10760#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010761 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010762#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020010763#ifdef HAVE_GETGROUPLIST
10764 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
10765#endif
Fred Drakec9680921999-12-13 16:37:25 +000010766#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010767 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010768#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010769 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010770#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010771 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010772#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010773#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010774 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010775#endif /* HAVE_GETPPID */
10776#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010777 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010778#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000010779#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010780 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000010781#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000010782#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000010783 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010784#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010785#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000010786 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010787#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000010788#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010789 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000010790#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000010791#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010792 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
10793 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Brian Curtin1b9df392010-11-24 20:24:31 +000010794 {"link", win32_link, METH_VARARGS, win32_link__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000010795#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010796#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010797 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010798#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010799#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010800 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010801#endif /* HAVE_SETEUID */
10802#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010803 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010804#endif /* HAVE_SETEGID */
10805#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010806 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010807#endif /* HAVE_SETREUID */
10808#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010809 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010810#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010811#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010812 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010813#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010814#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010815 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010816#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000010817#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010818 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000010819#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000010820#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010821 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000010822#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010823#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010824 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010825#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010826#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010827 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010828#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010829#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010010830 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010831#endif /* HAVE_WAIT3 */
10832#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010010833 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010834#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010835#if defined(HAVE_WAITID) && !defined(__APPLE__)
10836 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
10837#endif
Tim Petersab034fa2002-02-01 11:27:43 +000010838#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010839 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010840#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010841#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010842 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010843#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010844#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010845 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010846#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010847#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010848 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010849#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010850#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010851 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010852#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010853#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010854 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010855#endif /* HAVE_TCSETPGRP */
Victor Stinner8c62be82010-05-06 00:08:46 +000010856 {"open", posix_open, METH_VARARGS, posix_open__doc__},
10857 {"close", posix_close, METH_VARARGS, posix_close__doc__},
10858 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
10859 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
10860 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
10861 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010862#ifdef HAVE_LOCKF
10863 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
10864#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010865 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
10866 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010867#ifdef HAVE_READV
10868 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
10869#endif
10870#ifdef HAVE_PREAD
10871 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
10872#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010873 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010874#ifdef HAVE_WRITEV
10875 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
10876#endif
10877#ifdef HAVE_PWRITE
10878 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
10879#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000010880#ifdef HAVE_SENDFILE
10881 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
10882 posix_sendfile__doc__},
10883#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010010884 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010885 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010886#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010887 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010888#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010889#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020010890 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010891#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010892#ifdef HAVE_MKFIFO
Victor Stinner8c62be82010-05-06 00:08:46 +000010893 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010894#endif
Neal Norwitz11690112002-07-30 01:08:28 +000010895#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinner8c62be82010-05-06 00:08:46 +000010896 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000010897#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010898#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000010899 {"major", posix_major, METH_VARARGS, posix_major__doc__},
10900 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
10901 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010902#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010903#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000010904 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010905#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010906#ifdef HAVE_TRUNCATE
10907 {"truncate", posix_truncate, METH_VARARGS, posix_truncate__doc__},
10908#endif
10909#ifdef HAVE_POSIX_FALLOCATE
10910 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
10911#endif
10912#ifdef HAVE_POSIX_FADVISE
10913 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
10914#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010915#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010916 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010917#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010918#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010919 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000010920#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010921 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010922#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000010923 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010924#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010925#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010926 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010927#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010928#ifdef HAVE_SYNC
10929 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
10930#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010931#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010932 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010933#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000010934#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010935#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000010936 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000010937#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010938#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000010939 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010940#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000010941#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000010942 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010943#endif /* WIFSTOPPED */
10944#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000010945 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010946#endif /* WIFSIGNALED */
10947#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000010948 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010949#endif /* WIFEXITED */
10950#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000010951 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010952#endif /* WEXITSTATUS */
10953#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010954 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010955#endif /* WTERMSIG */
10956#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010957 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010958#endif /* WSTOPSIG */
10959#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000010960#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000010961 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010962#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000010963#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000010964 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010965#endif
Fred Drakec9680921999-12-13 16:37:25 +000010966#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000010967 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010968#endif
10969#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010970 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010971#endif
10972#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010973 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010974#endif
10975#ifdef HAVE_PATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010976 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010977#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010978 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010979#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010980 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000010981 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +000010982 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050010983 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010984 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000010985#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000010986#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000010987 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000010988#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010010989 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010990#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010991 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010992#endif
10993#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010994 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010995#endif
10996#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010997 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010998#endif
10999#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011000 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011001#endif
11002
Antoine Pitrouf65132d2011-02-25 23:25:17 +000011003/* posix *at family of functions */
11004#ifdef HAVE_FACCESSAT
11005 {"faccessat", posix_faccessat, METH_VARARGS, posix_faccessat__doc__},
11006#endif
11007#ifdef HAVE_FCHMODAT
11008 {"fchmodat", posix_fchmodat, METH_VARARGS, posix_fchmodat__doc__},
11009#endif /* HAVE_FCHMODAT */
11010#ifdef HAVE_FCHOWNAT
11011 {"fchownat", posix_fchownat, METH_VARARGS, posix_fchownat__doc__},
11012#endif /* HAVE_FCHOWNAT */
11013#ifdef HAVE_FSTATAT
Victor Stinner4195b5c2012-02-08 23:03:19 +010011014 {"fstatat", posix_fstatat, METH_VARARGS, posix_fstatat__doc__},
Antoine Pitrouf65132d2011-02-25 23:25:17 +000011015#endif
11016#ifdef HAVE_FUTIMESAT
11017 {"futimesat", posix_futimesat, METH_VARARGS, posix_futimesat__doc__},
11018#endif
11019#ifdef HAVE_LINKAT
11020 {"linkat", posix_linkat, METH_VARARGS, posix_linkat__doc__},
11021#endif /* HAVE_LINKAT */
11022#ifdef HAVE_MKDIRAT
11023 {"mkdirat", posix_mkdirat, METH_VARARGS, posix_mkdirat__doc__},
11024#endif
11025#if defined(HAVE_MKNODAT) && defined(HAVE_MAKEDEV)
11026 {"mknodat", posix_mknodat, METH_VARARGS, posix_mknodat__doc__},
11027#endif
11028#ifdef HAVE_OPENAT
11029 {"openat", posix_openat, METH_VARARGS, posix_openat__doc__},
11030#endif
11031#ifdef HAVE_READLINKAT
11032 {"readlinkat", posix_readlinkat, METH_VARARGS, posix_readlinkat__doc__},
11033#endif /* HAVE_READLINKAT */
11034#ifdef HAVE_RENAMEAT
11035 {"renameat", posix_renameat, METH_VARARGS, posix_renameat__doc__},
11036#endif
11037#if HAVE_SYMLINKAT
11038 {"symlinkat", posix_symlinkat, METH_VARARGS, posix_symlinkat__doc__},
11039#endif /* HAVE_SYMLINKAT */
11040#ifdef HAVE_UNLINKAT
11041 {"unlinkat", posix_unlinkat, METH_VARARGS, posix_unlinkat__doc__},
11042#endif
11043#ifdef HAVE_UTIMENSAT
Jesus Cead03a4912011-11-08 17:28:04 +010011044 {"utimensat", (PyCFunction)posix_utimensat,
11045 METH_VARARGS | METH_KEYWORDS,
Brian Curtin569b4942011-11-07 16:09:20 -060011046 posix_utimensat__doc__},
Antoine Pitrouf65132d2011-02-25 23:25:17 +000011047#endif
11048#ifdef HAVE_MKFIFOAT
11049 {"mkfifoat", posix_mkfifoat, METH_VARARGS, posix_mkfifoat__doc__},
11050#endif
Benjamin Peterson9428d532011-09-14 11:45:52 -040011051#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011052 {"setxattr", posix_setxattr, METH_VARARGS, posix_setxattr__doc__},
11053 {"lsetxattr", posix_lsetxattr, METH_VARARGS, posix_lsetxattr__doc__},
11054 {"fsetxattr", posix_fsetxattr, METH_VARARGS, posix_fsetxattr__doc__},
11055 {"getxattr", posix_getxattr, METH_VARARGS, posix_getxattr__doc__},
11056 {"lgetxattr", posix_lgetxattr, METH_VARARGS, posix_lgetxattr__doc__},
11057 {"fgetxattr", posix_fgetxattr, METH_VARARGS, posix_fgetxattr__doc__},
11058 {"removexattr", posix_removexattr, METH_VARARGS, posix_removexattr__doc__},
11059 {"lremovexattr", posix_lremovexattr, METH_VARARGS, posix_lremovexattr__doc__},
11060 {"fremovexattr", posix_fremovexattr, METH_VARARGS, posix_fremovexattr__doc__},
11061 {"listxattr", posix_listxattr, METH_VARARGS, posix_listxattr__doc__},
11062 {"llistxattr", posix_llistxattr, METH_VARARGS, posix_llistxattr__doc__},
11063 {"flistxattr", posix_flistxattr, METH_VARARGS, posix_flistxattr__doc__},
11064#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011065#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11066 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11067#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011068 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011069};
11070
11071
Barry Warsaw4a342091996-12-19 23:50:02 +000011072static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011073ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000011074{
Victor Stinner8c62be82010-05-06 00:08:46 +000011075 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000011076}
11077
Guido van Rossumd48f2521997-12-05 22:19:34 +000011078#if defined(PYOS_OS2)
11079/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011080static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011081{
11082 APIRET rc;
11083 ULONG values[QSV_MAX+1];
11084 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +000011085 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +000011086
11087 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +000011088 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011089 Py_END_ALLOW_THREADS
11090
11091 if (rc != NO_ERROR) {
11092 os2_error(rc);
11093 return -1;
11094 }
11095
Fred Drake4d1e64b2002-04-15 19:40:07 +000011096 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
11097 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
11098 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
11099 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
11100 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
11101 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
11102 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011103
11104 switch (values[QSV_VERSION_MINOR]) {
11105 case 0: ver = "2.00"; break;
11106 case 10: ver = "2.10"; break;
11107 case 11: ver = "2.11"; break;
11108 case 30: ver = "3.00"; break;
11109 case 40: ver = "4.00"; break;
11110 case 50: ver = "5.00"; break;
11111 default:
Tim Peters885d4572001-11-28 20:27:42 +000011112 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +000011113 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +000011114 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011115 ver = &tmp[0];
11116 }
11117
11118 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011119 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011120 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011121
11122 /* Add Indicator of Which Drive was Used to Boot the System */
11123 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
11124 tmp[1] = ':';
11125 tmp[2] = '\0';
11126
Fred Drake4d1e64b2002-04-15 19:40:07 +000011127 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011128}
11129#endif
11130
Brian Curtin52173d42010-12-02 18:29:18 +000011131#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011132static int
Brian Curtin52173d42010-12-02 18:29:18 +000011133enable_symlink()
11134{
11135 HANDLE tok;
11136 TOKEN_PRIVILEGES tok_priv;
11137 LUID luid;
11138 int meth_idx = 0;
11139
11140 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011141 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011142
11143 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011144 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011145
11146 tok_priv.PrivilegeCount = 1;
11147 tok_priv.Privileges[0].Luid = luid;
11148 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11149
11150 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11151 sizeof(TOKEN_PRIVILEGES),
11152 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011153 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011154
Brian Curtin3b4499c2010-12-28 14:31:47 +000011155 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11156 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011157}
11158#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11159
Barry Warsaw4a342091996-12-19 23:50:02 +000011160static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011161all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000011162{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011163#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011164 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011165#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011166#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011167 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011168#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011169#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011170 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011171#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011172#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011173 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011174#endif
Fred Drakec9680921999-12-13 16:37:25 +000011175#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011176 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011177#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011178#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011179 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011180#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011181#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011182 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011183#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011184#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000011185 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011186#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011187#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000011188 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011189#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011190#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011191 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011192#endif
11193#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011194 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011195#endif
11196#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000011197 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011198#endif
11199#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000011200 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011201#endif
11202#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011203 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011204#endif
11205#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000011206 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011207#endif
11208#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011209 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011210#endif
11211#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011212 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011213#endif
11214#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011215 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011216#endif
11217#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011218 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011219#endif
11220#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011221 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011222#endif
11223#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000011224 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011225#endif
11226#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011227 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011228#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011229#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011230 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011231#endif
11232#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000011233 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011234#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011235#ifdef O_XATTR
11236 if (ins(d, "O_XATTR", (long)O_XATTR)) return -1;
11237#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011238#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011239 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011240#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011241#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011242 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011243#endif
11244#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011245 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011246#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011247#ifdef O_EXEC
11248 if (ins(d, "O_EXEC", (long)O_EXEC)) return -1;
11249#endif
11250#ifdef O_SEARCH
11251 if (ins(d, "O_SEARCH", (long)O_SEARCH)) return -1;
11252#endif
11253#ifdef O_TTY_INIT
11254 if (ins(d, "O_TTY_INIT", (long)O_TTY_INIT)) return -1;
11255#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011256#ifdef PRIO_PROCESS
11257 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
11258#endif
11259#ifdef PRIO_PGRP
11260 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
11261#endif
11262#ifdef PRIO_USER
11263 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
11264#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011265#ifdef O_CLOEXEC
11266 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
11267#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011268#ifdef O_ACCMODE
11269 if (ins(d, "O_ACCMODE", (long)O_ACCMODE)) return -1;
11270#endif
Antoine Pitrouf65132d2011-02-25 23:25:17 +000011271/* posix - constants for *at functions */
11272#ifdef AT_SYMLINK_NOFOLLOW
11273 if (ins(d, "AT_SYMLINK_NOFOLLOW", (long)AT_SYMLINK_NOFOLLOW)) return -1;
11274#endif
11275#ifdef AT_EACCESS
11276 if (ins(d, "AT_EACCESS", (long)AT_EACCESS)) return -1;
11277#endif
11278#ifdef AT_FDCWD
11279 if (ins(d, "AT_FDCWD", (long)AT_FDCWD)) return -1;
11280#endif
11281#ifdef AT_REMOVEDIR
11282 if (ins(d, "AT_REMOVEDIR", (long)AT_REMOVEDIR)) return -1;
11283#endif
11284#ifdef AT_SYMLINK_FOLLOW
11285 if (ins(d, "AT_SYMLINK_FOLLOW", (long)AT_SYMLINK_FOLLOW)) return -1;
11286#endif
11287#ifdef UTIME_NOW
11288 if (ins(d, "UTIME_NOW", (long)UTIME_NOW)) return -1;
11289#endif
11290#ifdef UTIME_OMIT
11291 if (ins(d, "UTIME_OMIT", (long)UTIME_OMIT)) return -1;
11292#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011293
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011294
Tim Peters5aa91602002-01-30 05:46:57 +000011295/* MS Windows */
11296#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011297 /* Don't inherit in child processes. */
11298 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011299#endif
11300#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011301 /* Optimize for short life (keep in memory). */
11302 /* MS forgot to define this one with a non-underscore form too. */
11303 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011304#endif
11305#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011306 /* Automatically delete when last handle is closed. */
11307 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011308#endif
11309#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011310 /* Optimize for random access. */
11311 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011312#endif
11313#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011314 /* Optimize for sequential access. */
11315 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011316#endif
11317
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011318/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011319#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011320 /* Send a SIGIO signal whenever input or output
11321 becomes available on file descriptor */
11322 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011323#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011324#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011325 /* Direct disk access. */
11326 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011327#endif
11328#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011329 /* Must be a directory. */
11330 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011331#endif
11332#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011333 /* Do not follow links. */
11334 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011335#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011336#ifdef O_NOLINKS
11337 /* Fails if link count of the named file is greater than 1 */
11338 if (ins(d, "O_NOLINKS", (long)O_NOLINKS)) return -1;
11339#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011340#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011341 /* Do not update the access time. */
11342 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011343#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011344
Victor Stinner8c62be82010-05-06 00:08:46 +000011345 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011346#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011347 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011348#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011349#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011350 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011351#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011352#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011353 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011354#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011355#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011356 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011357#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011358#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000011359 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011360#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011361#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000011362 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011363#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011364#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011365 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011366#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011367#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000011368 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011369#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011370#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011371 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011372#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011373#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011374 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011375#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011376#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011377 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011378#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011379#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011380 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011381#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011382#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000011383 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011384#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011385#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000011386 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011387#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011388#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011389 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011390#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011391#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011392 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011393#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011394#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000011395 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011396#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011397
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011398 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011399#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011400 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011401#endif /* ST_RDONLY */
11402#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011403 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011404#endif /* ST_NOSUID */
11405
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011406 /* FreeBSD sendfile() constants */
11407#ifdef SF_NODISKIO
11408 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
11409#endif
11410#ifdef SF_MNOWAIT
11411 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
11412#endif
11413#ifdef SF_SYNC
11414 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
11415#endif
11416
Ross Lagerwall7807c352011-03-17 20:20:30 +020011417 /* constants for posix_fadvise */
11418#ifdef POSIX_FADV_NORMAL
11419 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
11420#endif
11421#ifdef POSIX_FADV_SEQUENTIAL
11422 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
11423#endif
11424#ifdef POSIX_FADV_RANDOM
11425 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
11426#endif
11427#ifdef POSIX_FADV_NOREUSE
11428 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
11429#endif
11430#ifdef POSIX_FADV_WILLNEED
11431 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
11432#endif
11433#ifdef POSIX_FADV_DONTNEED
11434 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
11435#endif
11436
11437 /* constants for waitid */
11438#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
11439 if (ins(d, "P_PID", (long)P_PID)) return -1;
11440 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
11441 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
11442#endif
11443#ifdef WEXITED
11444 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
11445#endif
11446#ifdef WNOWAIT
11447 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
11448#endif
11449#ifdef WSTOPPED
11450 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
11451#endif
11452#ifdef CLD_EXITED
11453 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
11454#endif
11455#ifdef CLD_DUMPED
11456 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
11457#endif
11458#ifdef CLD_TRAPPED
11459 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
11460#endif
11461#ifdef CLD_CONTINUED
11462 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
11463#endif
11464
11465 /* constants for lockf */
11466#ifdef F_LOCK
11467 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
11468#endif
11469#ifdef F_TLOCK
11470 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
11471#endif
11472#ifdef F_ULOCK
11473 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
11474#endif
11475#ifdef F_TEST
11476 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
11477#endif
11478
11479 /* constants for futimens */
11480#ifdef UTIME_NOW
11481 if (ins(d, "UTIME_NOW", (long)UTIME_NOW)) return -1;
11482#endif
11483#ifdef UTIME_OMIT
11484 if (ins(d, "UTIME_OMIT", (long)UTIME_OMIT)) return -1;
11485#endif
11486
Guido van Rossum246bc171999-02-01 23:54:31 +000011487#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011488#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +000011489 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
11490 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
11491 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
11492 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
11493 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
11494 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
11495 if (ins(d, "P_PM", (long)P_PM)) return -1;
11496 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
11497 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
11498 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
11499 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
11500 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
11501 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
11502 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
11503 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
11504 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
11505 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
11506 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
11507 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
11508 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011509#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011510 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
11511 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
11512 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
11513 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
11514 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011515#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011516#endif
Guido van Rossum246bc171999-02-01 23:54:31 +000011517
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011518#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011519 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011520 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11521 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11522#ifdef SCHED_SPORADIC
11523 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
11524#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011525#ifdef SCHED_BATCH
11526 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11527#endif
11528#ifdef SCHED_IDLE
11529 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11530#endif
11531#ifdef SCHED_RESET_ON_FORK
11532 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11533#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011534#ifdef SCHED_SYS
11535 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11536#endif
11537#ifdef SCHED_IA
11538 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11539#endif
11540#ifdef SCHED_FSS
11541 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11542#endif
11543#ifdef SCHED_FX
11544 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11545#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011546#endif
11547
Benjamin Peterson9428d532011-09-14 11:45:52 -040011548#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011549 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11550 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11551 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11552#endif
11553
Victor Stinner8b905bd2011-10-25 13:34:04 +020011554#ifdef RTLD_LAZY
11555 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11556#endif
11557#ifdef RTLD_NOW
11558 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11559#endif
11560#ifdef RTLD_GLOBAL
11561 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11562#endif
11563#ifdef RTLD_LOCAL
11564 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11565#endif
11566#ifdef RTLD_NODELETE
11567 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11568#endif
11569#ifdef RTLD_NOLOAD
11570 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11571#endif
11572#ifdef RTLD_DEEPBIND
11573 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11574#endif
11575
Guido van Rossumd48f2521997-12-05 22:19:34 +000011576#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000011577 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011578#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011579 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011580}
11581
11582
Tim Peters5aa91602002-01-30 05:46:57 +000011583#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011584#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011585#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011586
11587#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011588#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011589#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011590
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011591#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011592#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011593#define MODNAME "posix"
11594#endif
11595
Martin v. Löwis1a214512008-06-11 05:26:20 +000011596static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011597 PyModuleDef_HEAD_INIT,
11598 MODNAME,
11599 posix__doc__,
11600 -1,
11601 posix_methods,
11602 NULL,
11603 NULL,
11604 NULL,
11605 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011606};
11607
11608
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011609PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011610INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011611{
Victor Stinner8c62be82010-05-06 00:08:46 +000011612 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +000011613
Brian Curtin52173d42010-12-02 18:29:18 +000011614#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011615 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011616#endif
11617
Victor Stinner8c62be82010-05-06 00:08:46 +000011618 m = PyModule_Create(&posixmodule);
11619 if (m == NULL)
11620 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011621
Victor Stinner8c62be82010-05-06 00:08:46 +000011622 /* Initialize environ dictionary */
11623 v = convertenviron();
11624 Py_XINCREF(v);
11625 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11626 return NULL;
11627 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011628
Victor Stinner8c62be82010-05-06 00:08:46 +000011629 if (all_ins(m))
11630 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011631
Victor Stinner8c62be82010-05-06 00:08:46 +000011632 if (setup_confname_tables(m))
11633 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011634
Victor Stinner8c62be82010-05-06 00:08:46 +000011635 Py_INCREF(PyExc_OSError);
11636 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011637
Benjamin Peterson2740af82011-08-02 17:41:34 -050011638#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011639 if (PyType_Ready(&cpu_set_type) < 0)
11640 return NULL;
11641 Py_INCREF(&cpu_set_type);
11642 PyModule_AddObject(m, "cpu_set", (PyObject *)&cpu_set_type);
Benjamin Peterson2740af82011-08-02 17:41:34 -050011643#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011644
Guido van Rossumb3d39562000-01-31 18:41:26 +000011645#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011646 if (posix_putenv_garbage == NULL)
11647 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011648#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011649
Victor Stinner8c62be82010-05-06 00:08:46 +000011650 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011651#if defined(HAVE_WAITID) && !defined(__APPLE__)
11652 waitid_result_desc.name = MODNAME ".waitid_result";
11653 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
11654#endif
11655
Victor Stinner8c62be82010-05-06 00:08:46 +000011656 stat_result_desc.name = MODNAME ".stat_result";
11657 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11658 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11659 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
11660 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
11661 structseq_new = StatResultType.tp_new;
11662 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011663
Victor Stinner8c62be82010-05-06 00:08:46 +000011664 statvfs_result_desc.name = MODNAME ".statvfs_result";
11665 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011666#ifdef NEED_TICKS_PER_SECOND
11667# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011668 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011669# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011670 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011671# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011672 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011673# endif
11674#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011675
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050011676#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011677 sched_param_desc.name = MODNAME ".sched_param";
11678 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
11679 SchedParamType.tp_new = sched_param_new;
11680#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011681
11682 /* initialize TerminalSize_info */
11683 PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc);
11684 Py_INCREF(&TerminalSizeType);
Victor Stinner8c62be82010-05-06 00:08:46 +000011685 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011686#if defined(HAVE_WAITID) && !defined(__APPLE__)
11687 Py_INCREF((PyObject*) &WaitidResultType);
11688 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
11689#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011690 Py_INCREF((PyObject*) &StatResultType);
11691 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11692 Py_INCREF((PyObject*) &StatVFSResultType);
11693 PyModule_AddObject(m, "statvfs_result",
11694 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011695
11696#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011697 Py_INCREF(&SchedParamType);
11698 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011699#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011700 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011701
11702#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000011703 /*
11704 * Step 2 of weak-linking support on Mac OS X.
11705 *
11706 * The code below removes functions that are not available on the
11707 * currently active platform.
11708 *
11709 * This block allow one to use a python binary that was build on
11710 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
11711 * OSX 10.4.
11712 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011713#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011714 if (fstatvfs == NULL) {
11715 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
11716 return NULL;
11717 }
11718 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011719#endif /* HAVE_FSTATVFS */
11720
11721#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011722 if (statvfs == NULL) {
11723 if (PyObject_DelAttrString(m, "statvfs") == -1) {
11724 return NULL;
11725 }
11726 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011727#endif /* HAVE_STATVFS */
11728
11729# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011730 if (lchown == NULL) {
11731 if (PyObject_DelAttrString(m, "lchown") == -1) {
11732 return NULL;
11733 }
11734 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011735#endif /* HAVE_LCHOWN */
11736
11737
11738#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011739
11740 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
11741
Larry Hastings6fe20b32012-04-19 15:07:49 -070011742 billion = PyLong_FromLong(1000000000);
11743 if (!billion)
11744 return NULL;
11745
Victor Stinner8c62be82010-05-06 00:08:46 +000011746 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011747
Guido van Rossumb6775db1994-08-01 11:34:53 +000011748}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011749
11750#ifdef __cplusplus
11751}
11752#endif