blob: 0586da338a059e625728645b8dab354d1bdc5849 [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
Jesus Ceaab70e2a2012-10-05 01:48:08 +02004/* This file is also used for Windows NT/MS-Win. In that case the
5 module actually calls itself 'nt', not 'posix', and a few
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006 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
Jesus Ceaab70e2a2012-10-05 01:48:08 +02009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010
Thomas Wouters477c8d52006-05-27 19:21:47 +000011#ifdef __APPLE__
12 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000013 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000014 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
15 * at the end of this file for more information.
16 */
17# pragma weak lchown
18# pragma weak statvfs
19# pragma weak fstatvfs
20
21#endif /* __APPLE__ */
22
Thomas Wouters68bc4f92006-03-01 01:05:10 +000023#define PY_SSIZE_T_CLEAN
24
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000025#include "Python.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020026#ifndef MS_WINDOWS
27#include "posixmodule.h"
28#endif
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
Ross Lagerwall4d076da2011-03-18 06:56:53 +020046#ifdef HAVE_SYS_UIO_H
47#include <sys/uio.h>
48#endif
49
Thomas Wouters0e3f5912006-08-11 14:57:12 +000050#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000051#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000052#endif /* HAVE_SYS_TYPES_H */
53
54#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000055#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000056#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000057
Guido van Rossum36bc6801995-06-14 22:54:23 +000058#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000059#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000060#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000061
Thomas Wouters0e3f5912006-08-11 14:57:12 +000062#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000063#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000064#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000065
Guido van Rossumb6775db1994-08-01 11:34:53 +000066#ifdef HAVE_FCNTL_H
67#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000068#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000069
Guido van Rossuma6535fd2001-10-18 19:44:10 +000070#ifdef HAVE_GRP_H
71#include <grp.h>
72#endif
73
Barry Warsaw5676bd12003-01-07 20:57:09 +000074#ifdef HAVE_SYSEXITS_H
75#include <sysexits.h>
76#endif /* HAVE_SYSEXITS_H */
77
Anthony Baxter8a560de2004-10-13 15:30:56 +000078#ifdef HAVE_SYS_LOADAVG_H
79#include <sys/loadavg.h>
80#endif
81
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000082#ifdef HAVE_LANGINFO_H
83#include <langinfo.h>
84#endif
85
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000086#ifdef HAVE_SYS_SENDFILE_H
87#include <sys/sendfile.h>
88#endif
89
Benjamin Peterson94b580d2011-08-02 17:30:04 -050090#ifdef HAVE_SCHED_H
91#include <sched.h>
92#endif
93
Benjamin Peterson2dbda072012-03-16 10:12:55 -050094#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -050095#undef HAVE_SCHED_SETAFFINITY
96#endif
97
Benjamin Peterson9428d532011-09-14 11:45:52 -040098#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__)
99#define USE_XATTRS
100#endif
101
102#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400103#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400104#endif
105
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000106#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
107#ifdef HAVE_SYS_SOCKET_H
108#include <sys/socket.h>
109#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000110#endif
111
Victor Stinner8b905bd2011-10-25 13:34:04 +0200112#ifdef HAVE_DLFCN_H
113#include <dlfcn.h>
114#endif
115
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100116#if defined(MS_WINDOWS)
117# define TERMSIZE_USE_CONIO
118#elif defined(HAVE_SYS_IOCTL_H)
119# include <sys/ioctl.h>
120# if defined(HAVE_TERMIOS_H)
121# include <termios.h>
122# endif
123# if defined(TIOCGWINSZ)
124# define TERMSIZE_USE_IOCTL
125# endif
126#endif /* MS_WINDOWS */
127
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000128/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000129/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000130#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000131#define HAVE_GETCWD 1
132#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000133#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000134#include <process.h>
135#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000136#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000137#define HAVE_EXECV 1
138#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000139#define HAVE_OPENDIR 1
140#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000141#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000142#define HAVE_WAIT 1
143#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000144#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000145#define HAVE_GETCWD 1
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000146#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000147#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000148#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000149#define HAVE_EXECV 1
150#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000151#define HAVE_SYSTEM 1
152#define HAVE_CWAIT 1
153#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000154#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000155#else
Jesus Ceaab70e2a2012-10-05 01:48:08 +0200156#if defined(__VMS)
157/* Everything needed is defined in vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000158#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000159/* Unix functions that the configure script doesn't check for */
160#define HAVE_EXECV 1
161#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000162#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000163#define HAVE_FORK1 1
164#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000165#define HAVE_GETCWD 1
166#define HAVE_GETEGID 1
167#define HAVE_GETEUID 1
168#define HAVE_GETGID 1
169#define HAVE_GETPPID 1
170#define HAVE_GETUID 1
171#define HAVE_KILL 1
172#define HAVE_OPENDIR 1
173#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000174#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000175#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000176#define HAVE_TTYNAME 1
Jesus Ceaab70e2a2012-10-05 01:48:08 +0200177#endif /* __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000178#endif /* _MSC_VER */
179#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000180#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000181
Victor Stinnera2f7c002012-02-08 03:36:25 +0100182
183
184
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000185#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000186
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000187#if defined(__sgi)&&_COMPILER_VERSION>=700
188/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
189 (default) */
190extern char *ctermid_r(char *);
191#endif
192
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000193#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000194#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000195extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000196#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000197#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000198extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000199#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000200extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000201#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000202#endif
203#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000204extern int chdir(char *);
205extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000206#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000207extern int chdir(const char *);
208extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000209#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000210#ifdef __BORLANDC__
211extern int chmod(const char *, int);
212#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000213extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000214#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000215/*#ifdef HAVE_FCHMOD
216extern int fchmod(int, mode_t);
217#endif*/
218/*#ifdef HAVE_LCHMOD
219extern int lchmod(const char *, mode_t);
220#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000221extern int chown(const char *, uid_t, gid_t);
222extern char *getcwd(char *, int);
223extern char *strerror(int);
224extern int link(const char *, const char *);
225extern int rename(const char *, const char *);
226extern int stat(const char *, struct stat *);
227extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000228#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000229extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000230#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000231#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000232extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000233#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000235
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000236#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000237
Guido van Rossumb6775db1994-08-01 11:34:53 +0000238#ifdef HAVE_UTIME_H
239#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000240#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000242#ifdef HAVE_SYS_UTIME_H
243#include <sys/utime.h>
244#define HAVE_UTIME_H /* pretend we do for the rest of this file */
245#endif /* HAVE_SYS_UTIME_H */
246
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247#ifdef HAVE_SYS_TIMES_H
248#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000249#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000250
251#ifdef HAVE_SYS_PARAM_H
252#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000253#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254
255#ifdef HAVE_SYS_UTSNAME_H
256#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000257#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000259#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000261#define NAMLEN(dirent) strlen((dirent)->d_name)
262#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000263#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000264#include <direct.h>
265#define NAMLEN(dirent) strlen((dirent)->d_name)
266#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000267#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000268#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000269#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000270#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000272#endif
273#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000274#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000275#endif
276#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000277#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000278#endif
279#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000280
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000281#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000282#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000283#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000284#endif
285#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000286#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000287#endif
288#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000289#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000290#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000291#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000292#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000293#endif
294#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000295#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000296#endif
297#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000298#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000299#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000300#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000301#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000302#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000303#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000304#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000305#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
306#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000307static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000308#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000309#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000310
Tim Petersbc2e10e2002-03-03 23:17:02 +0000311#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000312#if defined(PATH_MAX) && PATH_MAX > 1024
313#define MAXPATHLEN PATH_MAX
314#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000315#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000316#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000317#endif /* MAXPATHLEN */
318
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000319#ifdef UNION_WAIT
320/* Emulate some macros on systems that have a union instead of macros */
321
322#ifndef WIFEXITED
323#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
324#endif
325
326#ifndef WEXITSTATUS
327#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
328#endif
329
330#ifndef WTERMSIG
331#define WTERMSIG(u_wait) ((u_wait).w_termsig)
332#endif
333
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000334#define WAIT_TYPE union wait
335#define WAIT_STATUS_INT(s) (s.w_status)
336
337#else /* !UNION_WAIT */
338#define WAIT_TYPE int
339#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000340#endif /* UNION_WAIT */
341
Greg Wardb48bc172000-03-01 21:51:56 +0000342/* Don't use the "_r" form if we don't need it (also, won't have a
343 prototype for it, at least on Solaris -- maybe others as well?). */
344#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
345#define USE_CTERMID_R
346#endif
347
Fred Drake699f3522000-06-29 21:12:41 +0000348/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000349#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000350#undef FSTAT
351#undef STRUCT_STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000352#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000353# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700354# define LSTAT win32_lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000355# define FSTAT win32_fstat
356# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000357#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000358# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700359# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000360# define FSTAT fstat
361# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000362#endif
363
Tim Peters11b23062003-04-23 02:39:17 +0000364#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000365#include <sys/mkdev.h>
366#else
367#if defined(MAJOR_IN_SYSMACROS)
368#include <sys/sysmacros.h>
369#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000370#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
371#include <sys/mkdev.h>
372#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000373#endif
Fred Drake699f3522000-06-29 21:12:41 +0000374
Larry Hastings9cf065c2012-06-22 16:30:09 -0700375
376#ifdef MS_WINDOWS
377static int
378win32_warn_bytes_api()
379{
380 return PyErr_WarnEx(PyExc_DeprecationWarning,
381 "The Windows bytes API has been deprecated, "
382 "use Unicode filenames instead",
383 1);
384}
385#endif
386
387
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200388#ifndef MS_WINDOWS
389PyObject *
390_PyLong_FromUid(uid_t uid)
391{
392 if (uid == (uid_t)-1)
393 return PyLong_FromLong(-1);
394 return PyLong_FromUnsignedLong(uid);
395}
396
397PyObject *
398_PyLong_FromGid(gid_t gid)
399{
400 if (gid == (gid_t)-1)
401 return PyLong_FromLong(-1);
402 return PyLong_FromUnsignedLong(gid);
403}
404
405int
406_Py_Uid_Converter(PyObject *obj, void *p)
407{
408 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200409 long result;
410 if (PyFloat_Check(obj)) {
411 PyErr_SetString(PyExc_TypeError,
412 "integer argument expected, got float");
413 return 0;
414 }
415 result = PyLong_AsLongAndOverflow(obj, &overflow);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200416 if (overflow < 0)
417 goto OverflowDown;
418 if (!overflow && result == -1) {
419 /* error or -1 */
420 if (PyErr_Occurred())
421 return 0;
422 *(uid_t *)p = (uid_t)-1;
423 }
424 else {
425 /* unsigned uid_t */
426 unsigned long uresult;
427 if (overflow > 0) {
428 uresult = PyLong_AsUnsignedLong(obj);
429 if (PyErr_Occurred()) {
430 if (PyErr_ExceptionMatches(PyExc_OverflowError))
431 goto OverflowUp;
432 return 0;
433 }
434 if ((uid_t)uresult == (uid_t)-1)
435 goto OverflowUp;
436 } else {
437 if (result < 0)
438 goto OverflowDown;
439 uresult = result;
440 }
441 if (sizeof(uid_t) < sizeof(long) &&
442 (unsigned long)(uid_t)uresult != uresult)
443 goto OverflowUp;
444 *(uid_t *)p = (uid_t)uresult;
445 }
446 return 1;
447
448OverflowDown:
449 PyErr_SetString(PyExc_OverflowError,
450 "user id is less than minimum");
451 return 0;
452
453OverflowUp:
454 PyErr_SetString(PyExc_OverflowError,
455 "user id is greater than maximum");
456 return 0;
457}
458
459int
460_Py_Gid_Converter(PyObject *obj, void *p)
461{
462 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200463 long result;
464 if (PyFloat_Check(obj)) {
465 PyErr_SetString(PyExc_TypeError,
466 "integer argument expected, got float");
467 return 0;
468 }
469 result = PyLong_AsLongAndOverflow(obj, &overflow);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200470 if (overflow < 0)
471 goto OverflowDown;
472 if (!overflow && result == -1) {
473 /* error or -1 */
474 if (PyErr_Occurred())
475 return 0;
476 *(gid_t *)p = (gid_t)-1;
477 }
478 else {
479 /* unsigned gid_t */
480 unsigned long uresult;
481 if (overflow > 0) {
482 uresult = PyLong_AsUnsignedLong(obj);
483 if (PyErr_Occurred()) {
484 if (PyErr_ExceptionMatches(PyExc_OverflowError))
485 goto OverflowUp;
486 return 0;
487 }
488 if ((gid_t)uresult == (gid_t)-1)
489 goto OverflowUp;
490 } else {
491 if (result < 0)
492 goto OverflowDown;
493 uresult = result;
494 }
495 if (sizeof(gid_t) < sizeof(long) &&
496 (unsigned long)(gid_t)uresult != uresult)
497 goto OverflowUp;
498 *(gid_t *)p = (gid_t)uresult;
499 }
500 return 1;
501
502OverflowDown:
503 PyErr_SetString(PyExc_OverflowError,
504 "group id is less than minimum");
505 return 0;
506
507OverflowUp:
508 PyErr_SetString(PyExc_OverflowError,
509 "group id is greater than maximum");
510 return 0;
511}
512#endif /* MS_WINDOWS */
513
514
Larry Hastings9cf065c2012-06-22 16:30:09 -0700515#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400516/*
517 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
518 * without the int cast, the value gets interpreted as uint (4291925331),
519 * which doesn't play nicely with all the initializer lines in this file that
520 * look like this:
521 * int dir_fd = DEFAULT_DIR_FD;
522 */
523#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700524#else
525#define DEFAULT_DIR_FD (-100)
526#endif
527
528static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200529_fd_converter(PyObject *o, int *p, const char *allowed)
530{
531 int overflow;
532 long long_value = PyLong_AsLongAndOverflow(o, &overflow);
533 if (PyFloat_Check(o) ||
534 (long_value == -1 && !overflow && PyErr_Occurred())) {
535 PyErr_Clear();
536 PyErr_Format(PyExc_TypeError,
537 "argument should be %s, not %.200s",
538 allowed, Py_TYPE(o)->tp_name);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700539 return 0;
540 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200541 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700542 PyErr_SetString(PyExc_OverflowError,
543 "signed integer is greater than maximum");
544 return 0;
545 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200546 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700547 PyErr_SetString(PyExc_OverflowError,
548 "signed integer is less than minimum");
549 return 0;
550 }
551 *p = (int)long_value;
552 return 1;
553}
554
555static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200556dir_fd_converter(PyObject *o, void *p)
557{
558 if (o == Py_None) {
559 *(int *)p = DEFAULT_DIR_FD;
560 return 1;
561 }
562 return _fd_converter(o, (int *)p, "integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700563}
564
565
566
567/*
568 * A PyArg_ParseTuple "converter" function
569 * that handles filesystem paths in the manner
570 * preferred by the os module.
571 *
572 * path_converter accepts (Unicode) strings and their
573 * subclasses, and bytes and their subclasses. What
574 * it does with the argument depends on the platform:
575 *
576 * * On Windows, if we get a (Unicode) string we
577 * extract the wchar_t * and return it; if we get
578 * bytes we extract the char * and return that.
579 *
580 * * On all other platforms, strings are encoded
581 * to bytes using PyUnicode_FSConverter, then we
582 * extract the char * from the bytes object and
583 * return that.
584 *
585 * path_converter also optionally accepts signed
586 * integers (representing open file descriptors) instead
587 * of path strings.
588 *
589 * Input fields:
590 * path.nullable
591 * If nonzero, the path is permitted to be None.
592 * path.allow_fd
593 * If nonzero, the path is permitted to be a file handle
594 * (a signed int) instead of a string.
595 * path.function_name
596 * If non-NULL, path_converter will use that as the name
597 * of the function in error messages.
598 * (If path.argument_name is NULL it omits the function name.)
599 * path.argument_name
600 * If non-NULL, path_converter will use that as the name
601 * of the parameter in error messages.
602 * (If path.argument_name is NULL it uses "path".)
603 *
604 * Output fields:
605 * path.wide
606 * Points to the path if it was expressed as Unicode
607 * and was not encoded. (Only used on Windows.)
608 * path.narrow
609 * Points to the path if it was expressed as bytes,
610 * or it was Unicode and was encoded to bytes.
611 * path.fd
612 * Contains a file descriptor if path.accept_fd was true
613 * and the caller provided a signed integer instead of any
614 * sort of string.
615 *
616 * WARNING: if your "path" parameter is optional, and is
617 * unspecified, path_converter will never get called.
618 * So if you set allow_fd, you *MUST* initialize path.fd = -1
619 * yourself!
620 * path.length
621 * The length of the path in characters, if specified as
622 * a string.
623 * path.object
624 * The original object passed in.
625 * path.cleanup
626 * For internal use only. May point to a temporary object.
627 * (Pay no attention to the man behind the curtain.)
628 *
629 * At most one of path.wide or path.narrow will be non-NULL.
630 * If path was None and path.nullable was set,
631 * or if path was an integer and path.allow_fd was set,
632 * both path.wide and path.narrow will be NULL
633 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200634 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700635 * path_converter takes care to not write to the path_t
636 * unless it's successful. However it must reset the
637 * "cleanup" field each time it's called.
638 *
639 * Use as follows:
640 * path_t path;
641 * memset(&path, 0, sizeof(path));
642 * PyArg_ParseTuple(args, "O&", path_converter, &path);
643 * // ... use values from path ...
644 * path_cleanup(&path);
645 *
646 * (Note that if PyArg_Parse fails you don't need to call
647 * path_cleanup(). However it is safe to do so.)
648 */
649typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100650 const char *function_name;
651 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700652 int nullable;
653 int allow_fd;
654 wchar_t *wide;
655 char *narrow;
656 int fd;
657 Py_ssize_t length;
658 PyObject *object;
659 PyObject *cleanup;
660} path_t;
661
662static void
663path_cleanup(path_t *path) {
664 if (path->cleanup) {
665 Py_DECREF(path->cleanup);
666 path->cleanup = NULL;
667 }
668}
669
670static int
671path_converter(PyObject *o, void *p) {
672 path_t *path = (path_t *)p;
673 PyObject *unicode, *bytes;
674 Py_ssize_t length;
675 char *narrow;
676
677#define FORMAT_EXCEPTION(exc, fmt) \
678 PyErr_Format(exc, "%s%s" fmt, \
679 path->function_name ? path->function_name : "", \
680 path->function_name ? ": " : "", \
681 path->argument_name ? path->argument_name : "path")
682
683 /* Py_CLEANUP_SUPPORTED support */
684 if (o == NULL) {
685 path_cleanup(path);
686 return 1;
687 }
688
689 /* ensure it's always safe to call path_cleanup() */
690 path->cleanup = NULL;
691
692 if (o == Py_None) {
693 if (!path->nullable) {
694 FORMAT_EXCEPTION(PyExc_TypeError,
695 "can't specify None for %s argument");
696 return 0;
697 }
698 path->wide = NULL;
699 path->narrow = NULL;
700 path->length = 0;
701 path->object = o;
702 path->fd = -1;
703 return 1;
704 }
705
706 unicode = PyUnicode_FromObject(o);
707 if (unicode) {
708#ifdef MS_WINDOWS
709 wchar_t *wide;
710 length = PyUnicode_GET_SIZE(unicode);
711 if (length > 32767) {
712 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
713 Py_DECREF(unicode);
714 return 0;
715 }
716
717 wide = PyUnicode_AsUnicode(unicode);
718 if (!wide) {
719 Py_DECREF(unicode);
720 return 0;
721 }
722
723 path->wide = wide;
724 path->narrow = NULL;
725 path->length = length;
726 path->object = o;
727 path->fd = -1;
728 path->cleanup = unicode;
729 return Py_CLEANUP_SUPPORTED;
730#else
731 int converted = PyUnicode_FSConverter(unicode, &bytes);
732 Py_DECREF(unicode);
733 if (!converted)
734 bytes = NULL;
735#endif
736 }
737 else {
738 PyErr_Clear();
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200739 if (PyObject_CheckBuffer(o))
740 bytes = PyBytes_FromObject(o);
741 else
742 bytes = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700743 if (!bytes) {
744 PyErr_Clear();
745 if (path->allow_fd) {
746 int fd;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200747 int result = _fd_converter(o, &fd,
748 "string, bytes or integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700749 if (result) {
750 path->wide = NULL;
751 path->narrow = NULL;
752 path->length = 0;
753 path->object = o;
754 path->fd = fd;
755 return result;
756 }
757 }
758 }
759 }
760
761 if (!bytes) {
762 if (!PyErr_Occurred())
763 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
764 return 0;
765 }
766
767#ifdef MS_WINDOWS
768 if (win32_warn_bytes_api()) {
769 Py_DECREF(bytes);
770 return 0;
771 }
772#endif
773
774 length = PyBytes_GET_SIZE(bytes);
775#ifdef MS_WINDOWS
776 if (length > MAX_PATH) {
777 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
778 Py_DECREF(bytes);
779 return 0;
780 }
781#endif
782
783 narrow = PyBytes_AS_STRING(bytes);
784 if (length != strlen(narrow)) {
785 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s");
786 Py_DECREF(bytes);
787 return 0;
788 }
789
790 path->wide = NULL;
791 path->narrow = narrow;
792 path->length = length;
793 path->object = o;
794 path->fd = -1;
795 path->cleanup = bytes;
796 return Py_CLEANUP_SUPPORTED;
797}
798
799static void
800argument_unavailable_error(char *function_name, char *argument_name) {
801 PyErr_Format(PyExc_NotImplementedError,
802 "%s%s%s unavailable on this platform",
803 (function_name != NULL) ? function_name : "",
804 (function_name != NULL) ? ": ": "",
805 argument_name);
806}
807
808static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200809dir_fd_unavailable(PyObject *o, void *p)
810{
811 int dir_fd;
812 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700813 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200814 if (dir_fd != DEFAULT_DIR_FD) {
815 argument_unavailable_error(NULL, "dir_fd");
816 return 0;
817 }
818 *(int *)p = dir_fd;
819 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700820}
821
822static int
823fd_specified(char *function_name, int fd) {
824 if (fd == -1)
825 return 0;
826
827 argument_unavailable_error(function_name, "fd");
828 return 1;
829}
830
831static int
832follow_symlinks_specified(char *function_name, int follow_symlinks) {
833 if (follow_symlinks)
834 return 0;
835
836 argument_unavailable_error(function_name, "follow_symlinks");
837 return 1;
838}
839
840static int
841path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
842 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
843 PyErr_Format(PyExc_ValueError,
844 "%s: can't specify dir_fd without matching path",
845 function_name);
846 return 1;
847 }
848 return 0;
849}
850
851static int
852dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
853 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
854 PyErr_Format(PyExc_ValueError,
855 "%s: can't specify both dir_fd and fd",
856 function_name);
857 return 1;
858 }
859 return 0;
860}
861
862static int
863fd_and_follow_symlinks_invalid(char *function_name, int fd,
864 int follow_symlinks) {
865 if ((fd > 0) && (!follow_symlinks)) {
866 PyErr_Format(PyExc_ValueError,
867 "%s: cannot use fd and follow_symlinks together",
868 function_name);
869 return 1;
870 }
871 return 0;
872}
873
874static int
875dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
876 int follow_symlinks) {
877 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
878 PyErr_Format(PyExc_ValueError,
879 "%s: cannot use dir_fd and follow_symlinks together",
880 function_name);
881 return 1;
882 }
883 return 0;
884}
885
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200886/* A helper used by a number of POSIX-only functions */
887#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +0000888static int
889_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000890{
891#if !defined(HAVE_LARGEFILE_SUPPORT)
892 *((off_t*)addr) = PyLong_AsLong(arg);
893#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +0000894 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000895#endif
896 if (PyErr_Occurred())
897 return 0;
898 return 1;
899}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200900#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000901
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000902#if defined _MSC_VER && _MSC_VER >= 1400
903/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
Andrew Svetlov737fb892012-12-18 21:14:22 +0200904 * valid and raise an assertion if it isn't.
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000905 * Normally, an invalid fd is likely to be a C program error and therefore
906 * an assertion can be useful, but it does contradict the POSIX standard
907 * which for write(2) states:
908 * "Otherwise, -1 shall be returned and errno set to indicate the error."
909 * "[EBADF] The fildes argument is not a valid file descriptor open for
910 * writing."
911 * Furthermore, python allows the user to enter any old integer
912 * as a fd and should merely raise a python exception on error.
913 * The Microsoft CRT doesn't provide an official way to check for the
914 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000915 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000916 * internal structures involved.
917 * The structures below must be updated for each version of visual studio
918 * according to the file internal.h in the CRT source, until MS comes
919 * up with a less hacky way to do this.
920 * (all of this is to avoid globally modifying the CRT behaviour using
921 * _set_invalid_parameter_handler() and _CrtSetReportMode())
922 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000923/* The actual size of the structure is determined at runtime.
924 * Only the first items must be present.
925 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000926typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000927 intptr_t osfhnd;
928 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000929} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000930
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000931extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000932#define IOINFO_L2E 5
933#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
934#define IOINFO_ARRAYS 64
935#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
936#define FOPEN 0x01
937#define _NO_CONSOLE_FILENO (intptr_t)-2
938
939/* This function emulates what the windows CRT does to validate file handles */
940int
941_PyVerify_fd(int fd)
942{
Victor Stinner8c62be82010-05-06 00:08:46 +0000943 const int i1 = fd >> IOINFO_L2E;
944 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000945
Antoine Pitrou22e41552010-08-15 18:07:50 +0000946 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000947
Victor Stinner8c62be82010-05-06 00:08:46 +0000948 /* Determine the actual size of the ioinfo structure,
949 * as used by the CRT loaded in memory
950 */
951 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
952 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
953 }
954 if (sizeof_ioinfo == 0) {
955 /* This should not happen... */
956 goto fail;
957 }
958
959 /* See that it isn't a special CLEAR fileno */
960 if (fd != _NO_CONSOLE_FILENO) {
961 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
962 * we check pointer validity and other info
963 */
964 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
965 /* finally, check that the file is open */
966 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
967 if (info->osfile & FOPEN) {
968 return 1;
969 }
970 }
971 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000972 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000973 errno = EBADF;
974 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000975}
976
977/* the special case of checking dup2. The target fd must be in a sensible range */
978static int
979_PyVerify_fd_dup2(int fd1, int fd2)
980{
Victor Stinner8c62be82010-05-06 00:08:46 +0000981 if (!_PyVerify_fd(fd1))
982 return 0;
983 if (fd2 == _NO_CONSOLE_FILENO)
984 return 0;
985 if ((unsigned)fd2 < _NHANDLE_)
986 return 1;
987 else
988 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000989}
990#else
991/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
992#define _PyVerify_fd_dup2(A, B) (1)
993#endif
994
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000995#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +0000996/* The following structure was copied from
997 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
998 include doesn't seem to be present in the Windows SDK (at least as included
999 with Visual Studio Express). */
1000typedef struct _REPARSE_DATA_BUFFER {
1001 ULONG ReparseTag;
1002 USHORT ReparseDataLength;
1003 USHORT Reserved;
1004 union {
1005 struct {
1006 USHORT SubstituteNameOffset;
1007 USHORT SubstituteNameLength;
1008 USHORT PrintNameOffset;
1009 USHORT PrintNameLength;
1010 ULONG Flags;
1011 WCHAR PathBuffer[1];
1012 } SymbolicLinkReparseBuffer;
1013
1014 struct {
1015 USHORT SubstituteNameOffset;
1016 USHORT SubstituteNameLength;
1017 USHORT PrintNameOffset;
1018 USHORT PrintNameLength;
1019 WCHAR PathBuffer[1];
1020 } MountPointReparseBuffer;
1021
1022 struct {
1023 UCHAR DataBuffer[1];
1024 } GenericReparseBuffer;
1025 };
1026} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
1027
1028#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
1029 GenericReparseBuffer)
1030#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
1031
1032static int
Brian Curtind25aef52011-06-13 15:16:04 -05001033win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001034{
1035 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1036 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
1037 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001038
1039 if (0 == DeviceIoControl(
1040 reparse_point_handle,
1041 FSCTL_GET_REPARSE_POINT,
1042 NULL, 0, /* in buffer */
1043 target_buffer, sizeof(target_buffer),
1044 &n_bytes_returned,
1045 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001046 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001047
1048 if (reparse_tag)
1049 *reparse_tag = rdb->ReparseTag;
1050
Brian Curtind25aef52011-06-13 15:16:04 -05001051 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001052}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001053
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001054#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001055
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001056/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001057#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001058/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001059** environ directly, we must obtain it with _NSGetEnviron(). See also
1060** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001061*/
1062#include <crt_externs.h>
1063static char **environ;
1064#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001065extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001066#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001067
Barry Warsaw53699e91996-12-10 23:23:01 +00001068static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001069convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001070{
Victor Stinner8c62be82010-05-06 00:08:46 +00001071 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001072#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001073 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001074#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001075 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001076#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001077
Victor Stinner8c62be82010-05-06 00:08:46 +00001078 d = PyDict_New();
1079 if (d == NULL)
1080 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001081#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001082 if (environ == NULL)
1083 environ = *_NSGetEnviron();
1084#endif
1085#ifdef MS_WINDOWS
1086 /* _wenviron must be initialized in this way if the program is started
1087 through main() instead of wmain(). */
1088 _wgetenv(L"");
1089 if (_wenviron == NULL)
1090 return d;
1091 /* This part ignores errors */
1092 for (e = _wenviron; *e != NULL; e++) {
1093 PyObject *k;
1094 PyObject *v;
1095 wchar_t *p = wcschr(*e, L'=');
1096 if (p == NULL)
1097 continue;
1098 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1099 if (k == NULL) {
1100 PyErr_Clear();
1101 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001102 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001103 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1104 if (v == NULL) {
1105 PyErr_Clear();
1106 Py_DECREF(k);
1107 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001108 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001109 if (PyDict_GetItem(d, k) == NULL) {
1110 if (PyDict_SetItem(d, k, v) != 0)
1111 PyErr_Clear();
1112 }
1113 Py_DECREF(k);
1114 Py_DECREF(v);
1115 }
1116#else
1117 if (environ == NULL)
1118 return d;
1119 /* This part ignores errors */
1120 for (e = environ; *e != NULL; e++) {
1121 PyObject *k;
1122 PyObject *v;
1123 char *p = strchr(*e, '=');
1124 if (p == NULL)
1125 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001126 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001127 if (k == NULL) {
1128 PyErr_Clear();
1129 continue;
1130 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001131 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001132 if (v == NULL) {
1133 PyErr_Clear();
1134 Py_DECREF(k);
1135 continue;
1136 }
1137 if (PyDict_GetItem(d, k) == NULL) {
1138 if (PyDict_SetItem(d, k, v) != 0)
1139 PyErr_Clear();
1140 }
1141 Py_DECREF(k);
1142 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001143 }
1144#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001145 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001146}
1147
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001148/* Set a POSIX-specific error from errno, and return NULL */
1149
Barry Warsawd58d7641998-07-23 16:14:40 +00001150static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001151posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001152{
Victor Stinner8c62be82010-05-06 00:08:46 +00001153 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001154}
Mark Hammondef8b6542001-05-13 08:04:26 +00001155
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001156#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001157static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001158win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001159{
Victor Stinner8c62be82010-05-06 00:08:46 +00001160 /* XXX We should pass the function name along in the future.
1161 (winreg.c also wants to pass the function name.)
1162 This would however require an additional param to the
1163 Windows error object, which is non-trivial.
1164 */
1165 errno = GetLastError();
1166 if (filename)
1167 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1168 else
1169 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001170}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001171
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001172static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001173win32_error_object(char* function, PyObject* filename)
1174{
1175 /* XXX - see win32_error for comments on 'function' */
1176 errno = GetLastError();
1177 if (filename)
1178 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001179 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001180 errno,
1181 filename);
1182 else
1183 return PyErr_SetFromWindowsErr(errno);
1184}
1185
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001186#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001187
Larry Hastings9cf065c2012-06-22 16:30:09 -07001188static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001189path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001190{
1191#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001192 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1193 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001194#else
Victor Stinner292c8352012-10-30 02:17:38 +01001195 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001196#endif
1197}
1198
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001199/* POSIX generic methods */
1200
Barry Warsaw53699e91996-12-10 23:23:01 +00001201static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001202posix_fildes(PyObject *fdobj, int (*func)(int))
1203{
Victor Stinner8c62be82010-05-06 00:08:46 +00001204 int fd;
1205 int res;
1206 fd = PyObject_AsFileDescriptor(fdobj);
1207 if (fd < 0)
1208 return NULL;
1209 if (!_PyVerify_fd(fd))
1210 return posix_error();
1211 Py_BEGIN_ALLOW_THREADS
1212 res = (*func)(fd);
1213 Py_END_ALLOW_THREADS
1214 if (res < 0)
1215 return posix_error();
1216 Py_INCREF(Py_None);
1217 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001218}
Guido van Rossum21142a01999-01-08 21:05:37 +00001219
1220static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001221posix_1str(const char *func_name, PyObject *args, char *format,
1222 int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001223{
Victor Stinner292c8352012-10-30 02:17:38 +01001224 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001225 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01001226 memset(&path, 0, sizeof(path));
1227 path.function_name = func_name;
Victor Stinner8c62be82010-05-06 00:08:46 +00001228 if (!PyArg_ParseTuple(args, format,
Victor Stinner292c8352012-10-30 02:17:38 +01001229 path_converter, &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00001230 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001231 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001232 res = (*func)(path.narrow);
Victor Stinner8c62be82010-05-06 00:08:46 +00001233 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001234 if (res < 0) {
1235 path_error(&path);
1236 path_cleanup(&path);
1237 return NULL;
1238 }
1239 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001240 Py_INCREF(Py_None);
1241 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001242}
1243
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001244
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001245#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001246/* This is a reimplementation of the C library's chdir function,
1247 but one that produces Win32 errors instead of DOS error codes.
1248 chdir is essentially a wrapper around SetCurrentDirectory; however,
1249 it also needs to set "magic" environment variables indicating
1250 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001251static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001252win32_chdir(LPCSTR path)
1253{
Victor Stinner8c62be82010-05-06 00:08:46 +00001254 char new_path[MAX_PATH+1];
1255 int result;
1256 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001257
Victor Stinner8c62be82010-05-06 00:08:46 +00001258 if(!SetCurrentDirectoryA(path))
1259 return FALSE;
1260 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
1261 if (!result)
1262 return FALSE;
1263 /* In the ANSI API, there should not be any paths longer
1264 than MAX_PATH. */
1265 assert(result <= MAX_PATH+1);
1266 if (strncmp(new_path, "\\\\", 2) == 0 ||
1267 strncmp(new_path, "//", 2) == 0)
1268 /* UNC path, nothing to do. */
1269 return TRUE;
1270 env[1] = new_path[0];
1271 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001272}
1273
1274/* The Unicode version differs from the ANSI version
1275 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001276static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001277win32_wchdir(LPCWSTR path)
1278{
Victor Stinner8c62be82010-05-06 00:08:46 +00001279 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
1280 int result;
1281 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001282
Victor Stinner8c62be82010-05-06 00:08:46 +00001283 if(!SetCurrentDirectoryW(path))
1284 return FALSE;
1285 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
1286 if (!result)
1287 return FALSE;
1288 if (result > MAX_PATH+1) {
1289 new_path = malloc(result * sizeof(wchar_t));
1290 if (!new_path) {
1291 SetLastError(ERROR_OUTOFMEMORY);
1292 return FALSE;
1293 }
1294 result = GetCurrentDirectoryW(result, new_path);
1295 if (!result) {
1296 free(new_path);
1297 return FALSE;
1298 }
1299 }
1300 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1301 wcsncmp(new_path, L"//", 2) == 0)
1302 /* UNC path, nothing to do. */
1303 return TRUE;
1304 env[1] = new_path[0];
1305 result = SetEnvironmentVariableW(env, new_path);
1306 if (new_path != _new_path)
1307 free(new_path);
1308 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001309}
1310#endif
1311
Martin v. Löwis14694662006-02-03 12:54:16 +00001312#ifdef MS_WINDOWS
1313/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1314 - time stamps are restricted to second resolution
1315 - file modification times suffer from forth-and-back conversions between
1316 UTC and local time
1317 Therefore, we implement our own stat, based on the Win32 API directly.
1318*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001319#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001320
1321struct win32_stat{
Brian Curtin87e63a22012-12-31 11:59:48 -06001322 unsigned long st_dev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001323 __int64 st_ino;
1324 unsigned short st_mode;
1325 int st_nlink;
1326 int st_uid;
1327 int st_gid;
Brian Curtin87e63a22012-12-31 11:59:48 -06001328 unsigned long st_rdev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001329 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001330 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001331 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001332 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001333 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001334 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001335 int st_ctime_nsec;
1336};
1337
1338static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1339
1340static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001341FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001342{
Victor Stinner8c62be82010-05-06 00:08:46 +00001343 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1344 /* Cannot simply cast and dereference in_ptr,
1345 since it might not be aligned properly */
1346 __int64 in;
1347 memcpy(&in, in_ptr, sizeof(in));
1348 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001349 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001350}
1351
Thomas Wouters477c8d52006-05-27 19:21:47 +00001352static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001353time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001354{
Victor Stinner8c62be82010-05-06 00:08:46 +00001355 /* XXX endianness */
1356 __int64 out;
1357 out = time_in + secs_between_epochs;
1358 out = out * 10000000 + nsec_in / 100;
1359 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001360}
1361
Martin v. Löwis14694662006-02-03 12:54:16 +00001362/* Below, we *know* that ugo+r is 0444 */
1363#if _S_IREAD != 0400
1364#error Unsupported C library
1365#endif
1366static int
1367attributes_to_mode(DWORD attr)
1368{
Victor Stinner8c62be82010-05-06 00:08:46 +00001369 int m = 0;
1370 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1371 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1372 else
1373 m |= _S_IFREG;
1374 if (attr & FILE_ATTRIBUTE_READONLY)
1375 m |= 0444;
1376 else
1377 m |= 0666;
1378 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001379}
1380
1381static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001382attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001383{
Victor Stinner8c62be82010-05-06 00:08:46 +00001384 memset(result, 0, sizeof(*result));
1385 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1386 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
Brian Curtin490b32a2012-12-26 07:03:03 -06001387 result->st_dev = info->dwVolumeSerialNumber;
1388 result->st_rdev = result->st_dev;
Victor Stinner8c62be82010-05-06 00:08:46 +00001389 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1390 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1391 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001392 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001393 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001394 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1395 /* first clear the S_IFMT bits */
1396 result->st_mode ^= (result->st_mode & 0170000);
1397 /* now set the bits that make this a symlink */
1398 result->st_mode |= 0120000;
1399 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001400
Victor Stinner8c62be82010-05-06 00:08:46 +00001401 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001402}
1403
Guido van Rossumd8faa362007-04-27 19:54:29 +00001404static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001405attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001406{
Victor Stinner8c62be82010-05-06 00:08:46 +00001407 HANDLE hFindFile;
1408 WIN32_FIND_DATAA FileData;
1409 hFindFile = FindFirstFileA(pszFile, &FileData);
1410 if (hFindFile == INVALID_HANDLE_VALUE)
1411 return FALSE;
1412 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001413 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001414 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001415 info->dwFileAttributes = FileData.dwFileAttributes;
1416 info->ftCreationTime = FileData.ftCreationTime;
1417 info->ftLastAccessTime = FileData.ftLastAccessTime;
1418 info->ftLastWriteTime = FileData.ftLastWriteTime;
1419 info->nFileSizeHigh = FileData.nFileSizeHigh;
1420 info->nFileSizeLow = FileData.nFileSizeLow;
1421/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001422 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1423 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001424 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001425}
1426
1427static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001428attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001429{
Victor Stinner8c62be82010-05-06 00:08:46 +00001430 HANDLE hFindFile;
1431 WIN32_FIND_DATAW FileData;
1432 hFindFile = FindFirstFileW(pszFile, &FileData);
1433 if (hFindFile == INVALID_HANDLE_VALUE)
1434 return FALSE;
1435 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001436 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001437 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001438 info->dwFileAttributes = FileData.dwFileAttributes;
1439 info->ftCreationTime = FileData.ftCreationTime;
1440 info->ftLastAccessTime = FileData.ftLastAccessTime;
1441 info->ftLastWriteTime = FileData.ftLastWriteTime;
1442 info->nFileSizeHigh = FileData.nFileSizeHigh;
1443 info->nFileSizeLow = FileData.nFileSizeLow;
1444/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001445 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1446 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001447 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001448}
1449
Brian Curtind25aef52011-06-13 15:16:04 -05001450/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001451static int has_GetFinalPathNameByHandle = -1;
Brian Curtind25aef52011-06-13 15:16:04 -05001452static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1453 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001454static int
Brian Curtind25aef52011-06-13 15:16:04 -05001455check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001456{
Brian Curtind25aef52011-06-13 15:16:04 -05001457 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001458 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1459 DWORD);
1460
Brian Curtind25aef52011-06-13 15:16:04 -05001461 /* only recheck */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001462 if (-1 == has_GetFinalPathNameByHandle)
Brian Curtind25aef52011-06-13 15:16:04 -05001463 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001464 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001465 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1466 "GetFinalPathNameByHandleA");
1467 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1468 "GetFinalPathNameByHandleW");
1469 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1470 Py_GetFinalPathNameByHandleW;
1471 }
1472 return has_GetFinalPathNameByHandle;
1473}
1474
1475static BOOL
1476get_target_path(HANDLE hdl, wchar_t **target_path)
1477{
1478 int buf_size, result_length;
1479 wchar_t *buf;
1480
1481 /* We have a good handle to the target, use it to determine
1482 the target path name (then we'll call lstat on it). */
1483 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1484 VOLUME_NAME_DOS);
1485 if(!buf_size)
1486 return FALSE;
1487
1488 buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001489 if (!buf) {
1490 SetLastError(ERROR_OUTOFMEMORY);
1491 return FALSE;
1492 }
1493
Brian Curtind25aef52011-06-13 15:16:04 -05001494 result_length = Py_GetFinalPathNameByHandleW(hdl,
1495 buf, buf_size, VOLUME_NAME_DOS);
1496
1497 if(!result_length) {
1498 free(buf);
1499 return FALSE;
1500 }
1501
1502 if(!CloseHandle(hdl)) {
1503 free(buf);
1504 return FALSE;
1505 }
1506
1507 buf[result_length] = 0;
1508
1509 *target_path = buf;
1510 return TRUE;
1511}
1512
1513static int
1514win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1515 BOOL traverse);
1516static int
1517win32_xstat_impl(const char *path, struct win32_stat *result,
1518 BOOL traverse)
1519{
Victor Stinner26de69d2011-06-17 15:15:38 +02001520 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001521 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001522 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001523 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001524 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001525 const char *dot;
1526
Brian Curtind25aef52011-06-13 15:16:04 -05001527 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001528 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1529 traverse reparse point. */
1530 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001531 }
1532
Brian Curtinf5e76d02010-11-24 13:14:05 +00001533 hFile = CreateFileA(
1534 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001535 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001536 0, /* share mode */
1537 NULL, /* security attributes */
1538 OPEN_EXISTING,
1539 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001540 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1541 Because of this, calls like GetFinalPathNameByHandle will return
1542 the symlink path agin and not the actual final path. */
1543 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1544 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001545 NULL);
1546
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001547 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001548 /* Either the target doesn't exist, or we don't have access to
1549 get a handle to it. If the former, we need to return an error.
1550 If the latter, we can use attributes_from_dir. */
1551 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001552 return -1;
1553 /* Could not get attributes on open file. Fall back to
1554 reading the directory. */
1555 if (!attributes_from_dir(path, &info, &reparse_tag))
1556 /* Very strange. This should not fail now */
1557 return -1;
1558 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1559 if (traverse) {
1560 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001561 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001562 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001563 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001564 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001565 } else {
1566 if (!GetFileInformationByHandle(hFile, &info)) {
1567 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001568 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001569 }
1570 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001571 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1572 return -1;
1573
1574 /* Close the outer open file handle now that we're about to
1575 reopen it with different flags. */
1576 if (!CloseHandle(hFile))
1577 return -1;
1578
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001579 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001580 /* In order to call GetFinalPathNameByHandle we need to open
1581 the file without the reparse handling flag set. */
1582 hFile2 = CreateFileA(
1583 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1584 NULL, OPEN_EXISTING,
1585 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1586 NULL);
1587 if (hFile2 == INVALID_HANDLE_VALUE)
1588 return -1;
1589
1590 if (!get_target_path(hFile2, &target_path))
1591 return -1;
1592
1593 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001594 free(target_path);
1595 return code;
1596 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001597 } else
1598 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001599 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001600 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001601
1602 /* Set S_IEXEC if it is an .exe, .bat, ... */
1603 dot = strrchr(path, '.');
1604 if (dot) {
1605 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1606 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1607 result->st_mode |= 0111;
1608 }
1609 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001610}
1611
1612static int
Brian Curtind25aef52011-06-13 15:16:04 -05001613win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1614 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001615{
1616 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001617 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001618 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001619 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001620 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001621 const wchar_t *dot;
1622
Brian Curtind25aef52011-06-13 15:16:04 -05001623 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001624 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1625 traverse reparse point. */
1626 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001627 }
1628
Brian Curtinf5e76d02010-11-24 13:14:05 +00001629 hFile = CreateFileW(
1630 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001631 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001632 0, /* share mode */
1633 NULL, /* security attributes */
1634 OPEN_EXISTING,
1635 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001636 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1637 Because of this, calls like GetFinalPathNameByHandle will return
1638 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001639 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001640 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001641 NULL);
1642
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001643 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001644 /* Either the target doesn't exist, or we don't have access to
1645 get a handle to it. If the former, we need to return an error.
1646 If the latter, we can use attributes_from_dir. */
1647 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001648 return -1;
1649 /* Could not get attributes on open file. Fall back to
1650 reading the directory. */
1651 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1652 /* Very strange. This should not fail now */
1653 return -1;
1654 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1655 if (traverse) {
1656 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001657 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001658 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001659 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001660 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001661 } else {
1662 if (!GetFileInformationByHandle(hFile, &info)) {
1663 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001664 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001665 }
1666 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001667 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1668 return -1;
1669
1670 /* Close the outer open file handle now that we're about to
1671 reopen it with different flags. */
1672 if (!CloseHandle(hFile))
1673 return -1;
1674
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001675 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001676 /* In order to call GetFinalPathNameByHandle we need to open
1677 the file without the reparse handling flag set. */
1678 hFile2 = CreateFileW(
1679 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1680 NULL, OPEN_EXISTING,
1681 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1682 NULL);
1683 if (hFile2 == INVALID_HANDLE_VALUE)
1684 return -1;
1685
1686 if (!get_target_path(hFile2, &target_path))
1687 return -1;
1688
1689 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001690 free(target_path);
1691 return code;
1692 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001693 } else
1694 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001695 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001696 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001697
1698 /* Set S_IEXEC if it is an .exe, .bat, ... */
1699 dot = wcsrchr(path, '.');
1700 if (dot) {
1701 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1702 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1703 result->st_mode |= 0111;
1704 }
1705 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001706}
1707
1708static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001709win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001710{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001711 /* Protocol violation: we explicitly clear errno, instead of
1712 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001713 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001714 errno = 0;
1715 return code;
1716}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001717
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001718static int
1719win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1720{
1721 /* Protocol violation: we explicitly clear errno, instead of
1722 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001723 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001724 errno = 0;
1725 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001726}
Brian Curtind25aef52011-06-13 15:16:04 -05001727/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001728
1729 In Posix, stat automatically traverses symlinks and returns the stat
1730 structure for the target. In Windows, the equivalent GetFileAttributes by
1731 default does not traverse symlinks and instead returns attributes for
1732 the symlink.
1733
1734 Therefore, win32_lstat will get the attributes traditionally, and
1735 win32_stat will first explicitly resolve the symlink target and then will
1736 call win32_lstat on that result.
1737
Ezio Melotti4969f702011-03-15 05:59:46 +02001738 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001739
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001740static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001741win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001742{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001743 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001744}
1745
Victor Stinner8c62be82010-05-06 00:08:46 +00001746static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001747win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001748{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001749 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001750}
1751
1752static int
1753win32_stat(const char* path, struct win32_stat *result)
1754{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001755 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001756}
1757
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001758static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001759win32_stat_w(const wchar_t* path, struct win32_stat *result)
1760{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001761 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001762}
1763
1764static int
1765win32_fstat(int file_number, struct win32_stat *result)
1766{
Victor Stinner8c62be82010-05-06 00:08:46 +00001767 BY_HANDLE_FILE_INFORMATION info;
1768 HANDLE h;
1769 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001770
Richard Oudkerk2240ac12012-07-06 12:05:32 +01001771 if (!_PyVerify_fd(file_number))
1772 h = INVALID_HANDLE_VALUE;
1773 else
1774 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001775
Victor Stinner8c62be82010-05-06 00:08:46 +00001776 /* Protocol violation: we explicitly clear errno, instead of
1777 setting it to a POSIX error. Callers should use GetLastError. */
1778 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001779
Victor Stinner8c62be82010-05-06 00:08:46 +00001780 if (h == INVALID_HANDLE_VALUE) {
1781 /* This is really a C library error (invalid file handle).
1782 We set the Win32 error to the closes one matching. */
1783 SetLastError(ERROR_INVALID_HANDLE);
1784 return -1;
1785 }
1786 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001787
Victor Stinner8c62be82010-05-06 00:08:46 +00001788 type = GetFileType(h);
1789 if (type == FILE_TYPE_UNKNOWN) {
1790 DWORD error = GetLastError();
1791 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001792 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001793 }
1794 /* else: valid but unknown file */
1795 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001796
Victor Stinner8c62be82010-05-06 00:08:46 +00001797 if (type != FILE_TYPE_DISK) {
1798 if (type == FILE_TYPE_CHAR)
1799 result->st_mode = _S_IFCHR;
1800 else if (type == FILE_TYPE_PIPE)
1801 result->st_mode = _S_IFIFO;
1802 return 0;
1803 }
1804
1805 if (!GetFileInformationByHandle(h, &info)) {
1806 return -1;
1807 }
1808
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001809 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001810 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001811 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1812 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001813}
1814
1815#endif /* MS_WINDOWS */
1816
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001817PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001818"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001819This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001820 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001821or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1822\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001823Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1824or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001825\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001826See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001827
1828static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001829 {"st_mode", "protection bits"},
1830 {"st_ino", "inode"},
1831 {"st_dev", "device"},
1832 {"st_nlink", "number of hard links"},
1833 {"st_uid", "user ID of owner"},
1834 {"st_gid", "group ID of owner"},
1835 {"st_size", "total size, in bytes"},
1836 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1837 {NULL, "integer time of last access"},
1838 {NULL, "integer time of last modification"},
1839 {NULL, "integer time of last change"},
1840 {"st_atime", "time of last access"},
1841 {"st_mtime", "time of last modification"},
1842 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001843 {"st_atime_ns", "time of last access in nanoseconds"},
1844 {"st_mtime_ns", "time of last modification in nanoseconds"},
1845 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001846#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001847 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001848#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001849#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001850 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001851#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001852#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001853 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001854#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001855#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001856 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001857#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001858#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001859 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001860#endif
1861#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001862 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001863#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001864 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001865};
1866
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001867#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001868#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001869#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001870#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001871#endif
1872
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001873#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001874#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1875#else
1876#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1877#endif
1878
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001879#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001880#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1881#else
1882#define ST_RDEV_IDX ST_BLOCKS_IDX
1883#endif
1884
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001885#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1886#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1887#else
1888#define ST_FLAGS_IDX ST_RDEV_IDX
1889#endif
1890
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001891#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001892#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001893#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001894#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001895#endif
1896
1897#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1898#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1899#else
1900#define ST_BIRTHTIME_IDX ST_GEN_IDX
1901#endif
1902
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001903static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001904 "stat_result", /* name */
1905 stat_result__doc__, /* doc */
1906 stat_result_fields,
1907 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001908};
1909
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001910PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001911"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1912This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001913 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001914or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001915\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001916See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001917
1918static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001919 {"f_bsize", },
1920 {"f_frsize", },
1921 {"f_blocks", },
1922 {"f_bfree", },
1923 {"f_bavail", },
1924 {"f_files", },
1925 {"f_ffree", },
1926 {"f_favail", },
1927 {"f_flag", },
1928 {"f_namemax",},
1929 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001930};
1931
1932static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001933 "statvfs_result", /* name */
1934 statvfs_result__doc__, /* doc */
1935 statvfs_result_fields,
1936 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001937};
1938
Ross Lagerwall7807c352011-03-17 20:20:30 +02001939#if defined(HAVE_WAITID) && !defined(__APPLE__)
1940PyDoc_STRVAR(waitid_result__doc__,
1941"waitid_result: Result from waitid.\n\n\
1942This object may be accessed either as a tuple of\n\
1943 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1944or via the attributes si_pid, si_uid, and so on.\n\
1945\n\
1946See os.waitid for more information.");
1947
1948static PyStructSequence_Field waitid_result_fields[] = {
1949 {"si_pid", },
1950 {"si_uid", },
1951 {"si_signo", },
1952 {"si_status", },
1953 {"si_code", },
1954 {0}
1955};
1956
1957static PyStructSequence_Desc waitid_result_desc = {
1958 "waitid_result", /* name */
1959 waitid_result__doc__, /* doc */
1960 waitid_result_fields,
1961 5
1962};
1963static PyTypeObject WaitidResultType;
1964#endif
1965
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001966static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001967static PyTypeObject StatResultType;
1968static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001969#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001970static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001971#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001972static newfunc structseq_new;
1973
1974static PyObject *
1975statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1976{
Victor Stinner8c62be82010-05-06 00:08:46 +00001977 PyStructSequence *result;
1978 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001979
Victor Stinner8c62be82010-05-06 00:08:46 +00001980 result = (PyStructSequence*)structseq_new(type, args, kwds);
1981 if (!result)
1982 return NULL;
1983 /* If we have been initialized from a tuple,
1984 st_?time might be set to None. Initialize it
1985 from the int slots. */
1986 for (i = 7; i <= 9; i++) {
1987 if (result->ob_item[i+3] == Py_None) {
1988 Py_DECREF(Py_None);
1989 Py_INCREF(result->ob_item[i]);
1990 result->ob_item[i+3] = result->ob_item[i];
1991 }
1992 }
1993 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001994}
1995
1996
1997
1998/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001999static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002000
2001PyDoc_STRVAR(stat_float_times__doc__,
2002"stat_float_times([newval]) -> oldval\n\n\
2003Determine whether os.[lf]stat represents time stamps as float objects.\n\
2004If newval is True, future calls to stat() return floats, if it is False,\n\
2005future calls return ints. \n\
2006If newval is omitted, return the current setting.\n");
2007
2008static PyObject*
2009stat_float_times(PyObject* self, PyObject *args)
2010{
Victor Stinner8c62be82010-05-06 00:08:46 +00002011 int newval = -1;
2012 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
2013 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02002014 if (PyErr_WarnEx(PyExc_DeprecationWarning,
2015 "stat_float_times() is deprecated",
2016 1))
2017 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002018 if (newval == -1)
2019 /* Return old value */
2020 return PyBool_FromLong(_stat_float_times);
2021 _stat_float_times = newval;
2022 Py_INCREF(Py_None);
2023 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002024}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002025
Larry Hastings6fe20b32012-04-19 15:07:49 -07002026static PyObject *billion = NULL;
2027
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002028static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002029fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002030{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002031 PyObject *s = _PyLong_FromTime_t(sec);
2032 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2033 PyObject *s_in_ns = NULL;
2034 PyObject *ns_total = NULL;
2035 PyObject *float_s = NULL;
2036
2037 if (!(s && ns_fractional))
2038 goto exit;
2039
2040 s_in_ns = PyNumber_Multiply(s, billion);
2041 if (!s_in_ns)
2042 goto exit;
2043
2044 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2045 if (!ns_total)
2046 goto exit;
2047
Victor Stinner4195b5c2012-02-08 23:03:19 +01002048 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002049 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2050 if (!float_s)
2051 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002052 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002053 else {
2054 float_s = s;
2055 Py_INCREF(float_s);
2056 }
2057
2058 PyStructSequence_SET_ITEM(v, index, s);
2059 PyStructSequence_SET_ITEM(v, index+3, float_s);
2060 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2061 s = NULL;
2062 float_s = NULL;
2063 ns_total = NULL;
2064exit:
2065 Py_XDECREF(s);
2066 Py_XDECREF(ns_fractional);
2067 Py_XDECREF(s_in_ns);
2068 Py_XDECREF(ns_total);
2069 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002070}
2071
Tim Peters5aa91602002-01-30 05:46:57 +00002072/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002073 (used by posix_stat() and posix_fstat()) */
2074static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002075_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002076{
Victor Stinner8c62be82010-05-06 00:08:46 +00002077 unsigned long ansec, mnsec, cnsec;
2078 PyObject *v = PyStructSequence_New(&StatResultType);
2079 if (v == NULL)
2080 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002081
Victor Stinner8c62be82010-05-06 00:08:46 +00002082 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002083#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002084 PyStructSequence_SET_ITEM(v, 1,
2085 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002086#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002087 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002088#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002089#ifdef MS_WINDOWS
2090 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
2091#elif defined(HAVE_LONG_LONG)
Victor Stinner8c62be82010-05-06 00:08:46 +00002092 PyStructSequence_SET_ITEM(v, 2,
2093 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002094#else
Brian Curtin9cc43212013-01-01 12:31:06 -06002095 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002096#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002097 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002098#if defined(MS_WINDOWS)
2099 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2100 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2101#else
2102 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2103 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2104#endif
Fred Drake699f3522000-06-29 21:12:41 +00002105#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002106 PyStructSequence_SET_ITEM(v, 6,
2107 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002108#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002109 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002110#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002111
Martin v. Löwis14694662006-02-03 12:54:16 +00002112#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002113 ansec = st->st_atim.tv_nsec;
2114 mnsec = st->st_mtim.tv_nsec;
2115 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002116#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002117 ansec = st->st_atimespec.tv_nsec;
2118 mnsec = st->st_mtimespec.tv_nsec;
2119 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002120#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002121 ansec = st->st_atime_nsec;
2122 mnsec = st->st_mtime_nsec;
2123 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002124#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002125 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002126#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002127 fill_time(v, 7, st->st_atime, ansec);
2128 fill_time(v, 8, st->st_mtime, mnsec);
2129 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002130
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002131#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002132 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2133 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002134#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002135#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002136 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2137 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002138#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002139#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002140 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2141 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002142#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002143#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002144 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2145 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002146#endif
2147#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002148 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002149 PyObject *val;
2150 unsigned long bsec,bnsec;
2151 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002152#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002153 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002154#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002155 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002156#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002157 if (_stat_float_times) {
2158 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2159 } else {
2160 val = PyLong_FromLong((long)bsec);
2161 }
2162 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2163 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002164 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002165#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002166#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002167 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2168 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002169#endif
Fred Drake699f3522000-06-29 21:12:41 +00002170
Victor Stinner8c62be82010-05-06 00:08:46 +00002171 if (PyErr_Occurred()) {
2172 Py_DECREF(v);
2173 return NULL;
2174 }
Fred Drake699f3522000-06-29 21:12:41 +00002175
Victor Stinner8c62be82010-05-06 00:08:46 +00002176 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002177}
2178
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002179/* POSIX methods */
2180
Guido van Rossum94f6f721999-01-06 18:42:14 +00002181
2182static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002183posix_do_stat(char *function_name, path_t *path,
2184 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002185{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002186 STRUCT_STAT st;
2187 int result;
2188
2189#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2190 if (follow_symlinks_specified(function_name, follow_symlinks))
2191 return NULL;
2192#endif
2193
2194 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2195 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2196 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2197 return NULL;
2198
2199 Py_BEGIN_ALLOW_THREADS
2200 if (path->fd != -1)
2201 result = FSTAT(path->fd, &st);
2202 else
2203#ifdef MS_WINDOWS
2204 if (path->wide) {
2205 if (follow_symlinks)
2206 result = win32_stat_w(path->wide, &st);
2207 else
2208 result = win32_lstat_w(path->wide, &st);
2209 }
2210 else
2211#endif
2212#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2213 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2214 result = LSTAT(path->narrow, &st);
2215 else
2216#endif
2217#ifdef HAVE_FSTATAT
2218 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2219 result = fstatat(dir_fd, path->narrow, &st,
2220 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2221 else
2222#endif
2223 result = STAT(path->narrow, &st);
2224 Py_END_ALLOW_THREADS
2225
Victor Stinner292c8352012-10-30 02:17:38 +01002226 if (result != 0) {
2227 return path_error(path);
2228 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002229
2230 return _pystat_fromstructstat(&st);
2231}
2232
2233PyDoc_STRVAR(posix_stat__doc__,
2234"stat(path, *, dir_fd=None, follow_symlinks=True) -> stat result\n\n\
2235Perform a stat system call on the given path.\n\
2236\n\
2237path may be specified as either a string or as an open file descriptor.\n\
2238\n\
2239If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2240 and path should be relative; path will then be relative to that directory.\n\
2241 dir_fd may not be supported on your platform; if it is unavailable, using\n\
2242 it will raise a NotImplementedError.\n\
2243If follow_symlinks is False, and the last element of the path is a symbolic\n\
2244 link, stat will examine the symbolic link itself instead of the file the\n\
2245 link points to.\n\
2246It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2247 an open file descriptor.");
2248
2249static PyObject *
2250posix_stat(PyObject *self, PyObject *args, PyObject *kwargs)
2251{
2252 static char *keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2253 path_t path;
2254 int dir_fd = DEFAULT_DIR_FD;
2255 int follow_symlinks = 1;
2256 PyObject *return_value;
2257
2258 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002259 path.function_name = "stat";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002260 path.allow_fd = 1;
2261 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:stat", keywords,
2262 path_converter, &path,
2263#ifdef HAVE_FSTATAT
2264 dir_fd_converter, &dir_fd,
2265#else
2266 dir_fd_unavailable, &dir_fd,
2267#endif
2268 &follow_symlinks))
2269 return NULL;
2270 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2271 path_cleanup(&path);
2272 return return_value;
2273}
2274
2275PyDoc_STRVAR(posix_lstat__doc__,
2276"lstat(path, *, dir_fd=None) -> stat result\n\n\
2277Like stat(), but do not follow symbolic links.\n\
2278Equivalent to stat(path, follow_symlinks=False).");
2279
2280static PyObject *
2281posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2282{
2283 static char *keywords[] = {"path", "dir_fd", NULL};
2284 path_t path;
2285 int dir_fd = DEFAULT_DIR_FD;
2286 int follow_symlinks = 0;
2287 PyObject *return_value;
2288
2289 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002290 path.function_name = "lstat";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002291 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2292 path_converter, &path,
2293#ifdef HAVE_FSTATAT
2294 dir_fd_converter, &dir_fd
2295#else
2296 dir_fd_unavailable, &dir_fd
2297#endif
2298 ))
2299 return NULL;
2300 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2301 path_cleanup(&path);
2302 return return_value;
2303}
2304
2305PyDoc_STRVAR(posix_access__doc__,
2306"access(path, mode, *, dir_fd=None, effective_ids=False,\
2307 follow_symlinks=True)\n\n\
2308Use the real uid/gid to test for access to a path. Returns True if granted,\n\
2309False otherwise.\n\
2310\n\
2311If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2312 and path should be relative; path will then be relative to that directory.\n\
2313If effective_ids is True, access will use the effective uid/gid instead of\n\
2314 the real uid/gid.\n\
2315If follow_symlinks is False, and the last element of the path is a symbolic\n\
2316 link, access will examine the symbolic link itself instead of the file the\n\
2317 link points to.\n\
2318dir_fd, effective_ids, and follow_symlinks may not be implemented\n\
2319 on your platform. If they are unavailable, using them will raise a\n\
2320 NotImplementedError.\n\
2321\n\
2322Note that most operations will use the effective uid/gid, therefore this\n\
2323 routine can be used in a suid/sgid environment to test if the invoking user\n\
2324 has the specified access to the path.\n\
2325The mode argument can be F_OK to test existence, or the inclusive-OR\n\
2326 of R_OK, W_OK, and X_OK.");
2327
2328static PyObject *
2329posix_access(PyObject *self, PyObject *args, PyObject *kwargs)
2330{
2331 static char *keywords[] = {"path", "mode", "dir_fd", "effective_ids",
2332 "follow_symlinks", NULL};
2333 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002334 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002335 int dir_fd = DEFAULT_DIR_FD;
2336 int effective_ids = 0;
2337 int follow_symlinks = 1;
2338 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002339
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002340#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002341 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002342#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002343 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002344#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002345
2346 memset(&path, 0, sizeof(path));
2347 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&pp:access", keywords,
2348 path_converter, &path, &mode,
2349#ifdef HAVE_FACCESSAT
2350 dir_fd_converter, &dir_fd,
2351#else
2352 dir_fd_unavailable, &dir_fd,
2353#endif
2354 &effective_ids, &follow_symlinks))
2355 return NULL;
2356
2357#ifndef HAVE_FACCESSAT
2358 if (follow_symlinks_specified("access", follow_symlinks))
2359 goto exit;
2360
2361 if (effective_ids) {
2362 argument_unavailable_error("access", "effective_ids");
2363 goto exit;
2364 }
2365#endif
2366
2367#ifdef MS_WINDOWS
2368 Py_BEGIN_ALLOW_THREADS
2369 if (path.wide != NULL)
2370 attr = GetFileAttributesW(path.wide);
2371 else
2372 attr = GetFileAttributesA(path.narrow);
2373 Py_END_ALLOW_THREADS
2374
2375 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002376 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002377 * * we didn't get a -1, and
2378 * * write access wasn't requested,
2379 * * or the file isn't read-only,
2380 * * or it's a directory.
2381 * (Directories cannot be read-only on Windows.)
2382 */
2383 return_value = PyBool_FromLong(
2384 (attr != 0xFFFFFFFF) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002385 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002386 !(attr & FILE_ATTRIBUTE_READONLY) ||
2387 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2388#else
2389
2390 Py_BEGIN_ALLOW_THREADS
2391#ifdef HAVE_FACCESSAT
2392 if ((dir_fd != DEFAULT_DIR_FD) ||
2393 effective_ids ||
2394 !follow_symlinks) {
2395 int flags = 0;
2396 if (!follow_symlinks)
2397 flags |= AT_SYMLINK_NOFOLLOW;
2398 if (effective_ids)
2399 flags |= AT_EACCESS;
2400 result = faccessat(dir_fd, path.narrow, mode, flags);
2401 }
2402 else
2403#endif
2404 result = access(path.narrow, mode);
2405 Py_END_ALLOW_THREADS
2406 return_value = PyBool_FromLong(!result);
2407#endif
2408
2409#ifndef HAVE_FACCESSAT
2410exit:
2411#endif
2412 path_cleanup(&path);
2413 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002414}
2415
Guido van Rossumd371ff11999-01-25 16:12:23 +00002416#ifndef F_OK
2417#define F_OK 0
2418#endif
2419#ifndef R_OK
2420#define R_OK 4
2421#endif
2422#ifndef W_OK
2423#define W_OK 2
2424#endif
2425#ifndef X_OK
2426#define X_OK 1
2427#endif
2428
2429#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002430PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002431"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002432Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00002433
2434static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002435posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002436{
Victor Stinner8c62be82010-05-06 00:08:46 +00002437 int id;
2438 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002439
Victor Stinner8c62be82010-05-06 00:08:46 +00002440 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
2441 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002442
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002443#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002444 /* file descriptor 0 only, the default input device (stdin) */
2445 if (id == 0) {
2446 ret = ttyname();
2447 }
2448 else {
2449 ret = NULL;
2450 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002451#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002452 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002453#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002454 if (ret == NULL)
2455 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002456 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002457}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002458#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002459
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002460#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002461PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002462"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002463Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002464
2465static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002466posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002467{
Victor Stinner8c62be82010-05-06 00:08:46 +00002468 char *ret;
2469 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002470
Greg Wardb48bc172000-03-01 21:51:56 +00002471#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002472 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002473#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002474 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002475#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002476 if (ret == NULL)
2477 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002478 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002479}
2480#endif
2481
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002482PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002483"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002484Change the current working directory to the specified path.\n\
2485\n\
2486path may always be specified as a string.\n\
2487On some platforms, path may also be specified as an open file descriptor.\n\
2488 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002489
Barry Warsaw53699e91996-12-10 23:23:01 +00002490static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002491posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002492{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002493 path_t path;
2494 int result;
2495 PyObject *return_value = NULL;
2496 static char *keywords[] = {"path", NULL};
2497
2498 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002499 path.function_name = "chdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002500#ifdef HAVE_FCHDIR
2501 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002502#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002503 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2504 path_converter, &path
2505 ))
2506 return NULL;
2507
2508 Py_BEGIN_ALLOW_THREADS
2509#ifdef MS_WINDOWS
2510 if (path.wide)
2511 result = win32_wchdir(path.wide);
2512 else
2513 result = win32_chdir(path.narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002514 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002515#else
2516#ifdef HAVE_FCHDIR
2517 if (path.fd != -1)
2518 result = fchdir(path.fd);
2519 else
2520#endif
2521 result = chdir(path.narrow);
2522#endif
2523 Py_END_ALLOW_THREADS
2524
2525 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002526 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002527 goto exit;
2528 }
2529
2530 return_value = Py_None;
2531 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02002532
Larry Hastings9cf065c2012-06-22 16:30:09 -07002533exit:
2534 path_cleanup(&path);
2535 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002536}
2537
Fred Drake4d1e64b2002-04-15 19:40:07 +00002538#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002539PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002540"fchdir(fd)\n\n\
2541Change to the directory of the given file descriptor. fd must be\n\
2542opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002543
2544static PyObject *
2545posix_fchdir(PyObject *self, PyObject *fdobj)
2546{
Victor Stinner8c62be82010-05-06 00:08:46 +00002547 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002548}
2549#endif /* HAVE_FCHDIR */
2550
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002551
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002552PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002553"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2554Change the access permissions of a file.\n\
2555\n\
2556path may always be specified as a string.\n\
2557On some platforms, path may also be specified as an open file descriptor.\n\
2558 If this functionality is unavailable, using it raises an exception.\n\
2559If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2560 and path should be relative; path will then be relative to that directory.\n\
2561If follow_symlinks is False, and the last element of the path is a symbolic\n\
2562 link, chmod will modify the symbolic link itself instead of the file the\n\
2563 link points to.\n\
2564It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2565 an open file descriptor.\n\
2566dir_fd and follow_symlinks may not be implemented on your platform.\n\
2567 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002568
Barry Warsaw53699e91996-12-10 23:23:01 +00002569static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002570posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002571{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002572 path_t path;
2573 int mode;
2574 int dir_fd = DEFAULT_DIR_FD;
2575 int follow_symlinks = 1;
2576 int result;
2577 PyObject *return_value = NULL;
2578 static char *keywords[] = {"path", "mode", "dir_fd",
2579 "follow_symlinks", NULL};
2580
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002581#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002582 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002583#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002584
Larry Hastings9cf065c2012-06-22 16:30:09 -07002585#ifdef HAVE_FCHMODAT
2586 int fchmodat_nofollow_unsupported = 0;
2587#endif
2588
2589 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002590 path.function_name = "chmod";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002591#ifdef HAVE_FCHMOD
2592 path.allow_fd = 1;
2593#endif
2594 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2595 path_converter, &path,
2596 &mode,
2597#ifdef HAVE_FCHMODAT
2598 dir_fd_converter, &dir_fd,
2599#else
2600 dir_fd_unavailable, &dir_fd,
2601#endif
2602 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002603 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002604
2605#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2606 if (follow_symlinks_specified("chmod", follow_symlinks))
2607 goto exit;
2608#endif
2609
2610#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002611 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002612 if (path.wide)
2613 attr = GetFileAttributesW(path.wide);
2614 else
2615 attr = GetFileAttributesA(path.narrow);
2616 if (attr == 0xFFFFFFFF)
2617 result = 0;
2618 else {
2619 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002620 attr &= ~FILE_ATTRIBUTE_READONLY;
2621 else
2622 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002623 if (path.wide)
2624 result = SetFileAttributesW(path.wide, attr);
2625 else
2626 result = SetFileAttributesA(path.narrow, attr);
2627 }
2628 Py_END_ALLOW_THREADS
2629
2630 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01002631 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002632 goto exit;
2633 }
2634#else /* MS_WINDOWS */
2635 Py_BEGIN_ALLOW_THREADS
2636#ifdef HAVE_FCHMOD
2637 if (path.fd != -1)
2638 result = fchmod(path.fd, mode);
2639 else
2640#endif
2641#ifdef HAVE_LCHMOD
2642 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2643 result = lchmod(path.narrow, mode);
2644 else
2645#endif
2646#ifdef HAVE_FCHMODAT
2647 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2648 /*
2649 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2650 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002651 * and then says it isn't implemented yet.
2652 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002653 *
2654 * Once it is supported, os.chmod will automatically
2655 * support dir_fd and follow_symlinks=False. (Hopefully.)
2656 * Until then, we need to be careful what exception we raise.
2657 */
2658 result = fchmodat(dir_fd, path.narrow, mode,
2659 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2660 /*
2661 * But wait! We can't throw the exception without allowing threads,
2662 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2663 */
2664 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002665 result &&
2666 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2667 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002668 }
2669 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002670#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002671 result = chmod(path.narrow, mode);
2672 Py_END_ALLOW_THREADS
2673
2674 if (result) {
2675#ifdef HAVE_FCHMODAT
2676 if (fchmodat_nofollow_unsupported) {
2677 if (dir_fd != DEFAULT_DIR_FD)
2678 dir_fd_and_follow_symlinks_invalid("chmod",
2679 dir_fd, follow_symlinks);
2680 else
2681 follow_symlinks_specified("chmod", follow_symlinks);
2682 }
2683 else
2684#endif
Victor Stinner292c8352012-10-30 02:17:38 +01002685 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002686 goto exit;
2687 }
2688#endif
2689
2690 Py_INCREF(Py_None);
2691 return_value = Py_None;
2692exit:
2693 path_cleanup(&path);
2694 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002695}
2696
Larry Hastings9cf065c2012-06-22 16:30:09 -07002697
Christian Heimes4e30a842007-11-30 22:12:06 +00002698#ifdef HAVE_FCHMOD
2699PyDoc_STRVAR(posix_fchmod__doc__,
2700"fchmod(fd, mode)\n\n\
2701Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002702descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002703
2704static PyObject *
2705posix_fchmod(PyObject *self, PyObject *args)
2706{
Victor Stinner8c62be82010-05-06 00:08:46 +00002707 int fd, mode, res;
2708 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2709 return NULL;
2710 Py_BEGIN_ALLOW_THREADS
2711 res = fchmod(fd, mode);
2712 Py_END_ALLOW_THREADS
2713 if (res < 0)
2714 return posix_error();
2715 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002716}
2717#endif /* HAVE_FCHMOD */
2718
2719#ifdef HAVE_LCHMOD
2720PyDoc_STRVAR(posix_lchmod__doc__,
2721"lchmod(path, mode)\n\n\
2722Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002723affects the link itself rather than the target.\n\
2724Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002725
2726static PyObject *
2727posix_lchmod(PyObject *self, PyObject *args)
2728{
Victor Stinner292c8352012-10-30 02:17:38 +01002729 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002730 int i;
2731 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01002732 memset(&path, 0, sizeof(path));
2733 path.function_name = "lchmod";
2734 if (!PyArg_ParseTuple(args, "O&i:lchmod",
2735 path_converter, &path, &i))
Victor Stinner8c62be82010-05-06 00:08:46 +00002736 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002737 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002738 res = lchmod(path.narrow, i);
Victor Stinner8c62be82010-05-06 00:08:46 +00002739 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002740 if (res < 0) {
2741 path_error(&path);
2742 path_cleanup(&path);
2743 return NULL;
2744 }
2745 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00002746 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002747}
2748#endif /* HAVE_LCHMOD */
2749
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002750
Thomas Wouterscf297e42007-02-23 15:07:44 +00002751#ifdef HAVE_CHFLAGS
2752PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002753"chflags(path, flags, *, follow_symlinks=True)\n\n\
2754Set file flags.\n\
2755\n\
2756If follow_symlinks is False, and the last element of the path is a symbolic\n\
2757 link, chflags will change flags on the symbolic link itself instead of the\n\
2758 file the link points to.\n\
2759follow_symlinks may not be implemented on your platform. If it is\n\
2760unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002761
2762static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002763posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00002764{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002765 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002766 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002767 int follow_symlinks = 1;
2768 int result;
2769 PyObject *return_value;
2770 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
2771
2772 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002773 path.function_name = "chflags";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002774 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
2775 path_converter, &path,
2776 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002777 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002778
2779#ifndef HAVE_LCHFLAGS
2780 if (follow_symlinks_specified("chflags", follow_symlinks))
2781 goto exit;
2782#endif
2783
Victor Stinner8c62be82010-05-06 00:08:46 +00002784 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002785#ifdef HAVE_LCHFLAGS
2786 if (!follow_symlinks)
2787 result = lchflags(path.narrow, flags);
2788 else
2789#endif
2790 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002791 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002792
2793 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002794 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002795 goto exit;
2796 }
2797
2798 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00002799 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002800
2801exit:
2802 path_cleanup(&path);
2803 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002804}
2805#endif /* HAVE_CHFLAGS */
2806
2807#ifdef HAVE_LCHFLAGS
2808PyDoc_STRVAR(posix_lchflags__doc__,
2809"lchflags(path, flags)\n\n\
2810Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002811This function will not follow symbolic links.\n\
2812Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002813
2814static PyObject *
2815posix_lchflags(PyObject *self, PyObject *args)
2816{
Victor Stinner292c8352012-10-30 02:17:38 +01002817 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002818 unsigned long flags;
2819 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01002820 memset(&path, 0, sizeof(path));
2821 path.function_name = "lchflags";
Victor Stinner8c62be82010-05-06 00:08:46 +00002822 if (!PyArg_ParseTuple(args, "O&k:lchflags",
Victor Stinner292c8352012-10-30 02:17:38 +01002823 path_converter, &path, &flags))
Victor Stinner8c62be82010-05-06 00:08:46 +00002824 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002825 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002826 res = lchflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002827 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002828 if (res < 0) {
2829 path_error(&path);
2830 path_cleanup(&path);
2831 return NULL;
2832 }
2833 path_cleanup(&path);
2834 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002835}
2836#endif /* HAVE_LCHFLAGS */
2837
Martin v. Löwis244edc82001-10-04 22:44:26 +00002838#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002839PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002840"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002841Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002842
2843static PyObject *
2844posix_chroot(PyObject *self, PyObject *args)
2845{
Victor Stinner292c8352012-10-30 02:17:38 +01002846 return posix_1str("chroot", args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002847}
2848#endif
2849
Guido van Rossum21142a01999-01-08 21:05:37 +00002850#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002851PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002852"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002853force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002854
2855static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002856posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002857{
Stefan Krah0e803b32010-11-26 16:16:47 +00002858 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002859}
2860#endif /* HAVE_FSYNC */
2861
Ross Lagerwall7807c352011-03-17 20:20:30 +02002862#ifdef HAVE_SYNC
2863PyDoc_STRVAR(posix_sync__doc__,
2864"sync()\n\n\
2865Force write of everything to disk.");
2866
2867static PyObject *
2868posix_sync(PyObject *self, PyObject *noargs)
2869{
2870 Py_BEGIN_ALLOW_THREADS
2871 sync();
2872 Py_END_ALLOW_THREADS
2873 Py_RETURN_NONE;
2874}
2875#endif
2876
Guido van Rossum21142a01999-01-08 21:05:37 +00002877#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002878
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002879#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002880extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2881#endif
2882
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002883PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002884"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002885force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002886 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002887
2888static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002889posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002890{
Stefan Krah0e803b32010-11-26 16:16:47 +00002891 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002892}
2893#endif /* HAVE_FDATASYNC */
2894
2895
Fredrik Lundh10723342000-07-10 16:38:09 +00002896#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002897PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002898"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
2899Change the owner and group id of path to the numeric uid and gid.\n\
2900\n\
2901path may always be specified as a string.\n\
2902On some platforms, path may also be specified as an open file descriptor.\n\
2903 If this functionality is unavailable, using it raises an exception.\n\
2904If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2905 and path should be relative; path will then be relative to that directory.\n\
2906If follow_symlinks is False, and the last element of the path is a symbolic\n\
2907 link, chown will modify the symbolic link itself instead of the file the\n\
2908 link points to.\n\
2909It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2910 an open file descriptor.\n\
2911dir_fd and follow_symlinks may not be implemented on your platform.\n\
2912 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002913
Barry Warsaw53699e91996-12-10 23:23:01 +00002914static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002915posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002916{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002917 path_t path;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002918 uid_t uid;
2919 gid_t gid;
2920 int dir_fd = DEFAULT_DIR_FD;
2921 int follow_symlinks = 1;
2922 int result;
2923 PyObject *return_value = NULL;
2924 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
2925 "follow_symlinks", NULL};
2926
2927 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002928 path.function_name = "chown";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002929#ifdef HAVE_FCHOWN
2930 path.allow_fd = 1;
2931#endif
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002932 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&|$O&p:chown", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002933 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002934 _Py_Uid_Converter, &uid,
2935 _Py_Gid_Converter, &gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002936#ifdef HAVE_FCHOWNAT
2937 dir_fd_converter, &dir_fd,
2938#else
2939 dir_fd_unavailable, &dir_fd,
2940#endif
2941 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002942 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002943
2944#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
2945 if (follow_symlinks_specified("chown", follow_symlinks))
2946 goto exit;
2947#endif
2948 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
2949 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
2950 goto exit;
2951
2952#ifdef __APPLE__
2953 /*
2954 * This is for Mac OS X 10.3, which doesn't have lchown.
2955 * (But we still have an lchown symbol because of weak-linking.)
2956 * It doesn't have fchownat either. So there's no possibility
2957 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02002958 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002959 if ((!follow_symlinks) && (lchown == NULL)) {
2960 follow_symlinks_specified("chown", follow_symlinks);
2961 goto exit;
2962 }
2963#endif
2964
Victor Stinner8c62be82010-05-06 00:08:46 +00002965 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002966#ifdef HAVE_FCHOWN
2967 if (path.fd != -1)
2968 result = fchown(path.fd, uid, gid);
2969 else
2970#endif
2971#ifdef HAVE_LCHOWN
2972 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2973 result = lchown(path.narrow, uid, gid);
2974 else
2975#endif
2976#ifdef HAVE_FCHOWNAT
2977 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
2978 result = fchownat(dir_fd, path.narrow, uid, gid,
2979 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2980 else
2981#endif
2982 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00002983 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002984
2985 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002986 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002987 goto exit;
2988 }
2989
2990 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00002991 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002992
2993exit:
2994 path_cleanup(&path);
2995 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002996}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002997#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002998
Christian Heimes4e30a842007-11-30 22:12:06 +00002999#ifdef HAVE_FCHOWN
3000PyDoc_STRVAR(posix_fchown__doc__,
3001"fchown(fd, uid, gid)\n\n\
3002Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003003fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003004
3005static PyObject *
3006posix_fchown(PyObject *self, PyObject *args)
3007{
Victor Stinner8c62be82010-05-06 00:08:46 +00003008 int fd;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003009 uid_t uid;
3010 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003011 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003012 if (!PyArg_ParseTuple(args, "iO&O&:fchown", &fd,
3013 _Py_Uid_Converter, &uid,
3014 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003015 return NULL;
3016 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003017 res = fchown(fd, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003018 Py_END_ALLOW_THREADS
3019 if (res < 0)
3020 return posix_error();
3021 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003022}
3023#endif /* HAVE_FCHOWN */
3024
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003025#ifdef HAVE_LCHOWN
3026PyDoc_STRVAR(posix_lchown__doc__,
3027"lchown(path, uid, gid)\n\n\
3028Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003029This function will not follow symbolic links.\n\
3030Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003031
3032static PyObject *
3033posix_lchown(PyObject *self, PyObject *args)
3034{
Victor Stinner292c8352012-10-30 02:17:38 +01003035 path_t path;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003036 uid_t uid;
3037 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003038 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003039 memset(&path, 0, sizeof(path));
3040 path.function_name = "lchown";
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003041 if (!PyArg_ParseTuple(args, "O&O&O&:lchown",
Victor Stinner292c8352012-10-30 02:17:38 +01003042 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003043 _Py_Uid_Converter, &uid,
3044 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003045 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003046 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakac2d02002013-02-10 22:03:08 +02003047 res = lchown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003048 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003049 if (res < 0) {
3050 path_error(&path);
3051 path_cleanup(&path);
3052 return NULL;
3053 }
3054 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003055 Py_INCREF(Py_None);
3056 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003057}
3058#endif /* HAVE_LCHOWN */
3059
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003060
Guido van Rossum36bc6801995-06-14 22:54:23 +00003061#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00003062static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003063posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003064{
Victor Stinner8c62be82010-05-06 00:08:46 +00003065 char buf[1026];
3066 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003067
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003068#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003069 if (!use_bytes) {
3070 wchar_t wbuf[1026];
3071 wchar_t *wbuf2 = wbuf;
3072 PyObject *resobj;
3073 DWORD len;
3074 Py_BEGIN_ALLOW_THREADS
3075 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
3076 /* If the buffer is large enough, len does not include the
3077 terminating \0. If the buffer is too small, len includes
3078 the space needed for the terminator. */
3079 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
3080 wbuf2 = malloc(len * sizeof(wchar_t));
3081 if (wbuf2)
3082 len = GetCurrentDirectoryW(len, wbuf2);
3083 }
3084 Py_END_ALLOW_THREADS
3085 if (!wbuf2) {
3086 PyErr_NoMemory();
3087 return NULL;
3088 }
3089 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003090 if (wbuf2 != wbuf)
3091 free(wbuf2);
3092 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003093 }
3094 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003095 if (wbuf2 != wbuf)
3096 free(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003097 return resobj;
3098 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003099
3100 if (win32_warn_bytes_api())
3101 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003102#endif
3103
Victor Stinner8c62be82010-05-06 00:08:46 +00003104 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003105 res = getcwd(buf, sizeof buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003106 Py_END_ALLOW_THREADS
3107 if (res == NULL)
3108 return posix_error();
3109 if (use_bytes)
3110 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00003111 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003112}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003113
3114PyDoc_STRVAR(posix_getcwd__doc__,
3115"getcwd() -> path\n\n\
3116Return a unicode string representing the current working directory.");
3117
3118static PyObject *
3119posix_getcwd_unicode(PyObject *self)
3120{
3121 return posix_getcwd(0);
3122}
3123
3124PyDoc_STRVAR(posix_getcwdb__doc__,
3125"getcwdb() -> path\n\n\
3126Return a bytes string representing the current working directory.");
3127
3128static PyObject *
3129posix_getcwd_bytes(PyObject *self)
3130{
3131 return posix_getcwd(1);
3132}
Guido van Rossum36bc6801995-06-14 22:54:23 +00003133#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003134
Larry Hastings9cf065c2012-06-22 16:30:09 -07003135#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3136#define HAVE_LINK 1
3137#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003138
Guido van Rossumb6775db1994-08-01 11:34:53 +00003139#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003140PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003141"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3142Create a hard link to a file.\n\
3143\n\
3144If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3145 descriptor open to a directory, and the respective path string (src or dst)\n\
3146 should be relative; the path will then be relative to that directory.\n\
3147If follow_symlinks is False, and the last element of src is a symbolic\n\
3148 link, link will create a link to the symbolic link itself instead of the\n\
3149 file the link points to.\n\
3150src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3151 platform. If they are unavailable, using them will raise a\n\
3152 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003153
Barry Warsaw53699e91996-12-10 23:23:01 +00003154static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003155posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003156{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003157 path_t src, dst;
3158 int src_dir_fd = DEFAULT_DIR_FD;
3159 int dst_dir_fd = DEFAULT_DIR_FD;
3160 int follow_symlinks = 1;
3161 PyObject *return_value = NULL;
3162 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3163 "follow_symlinks", NULL};
3164#ifdef MS_WINDOWS
3165 BOOL result;
3166#else
3167 int result;
3168#endif
3169
3170 memset(&src, 0, sizeof(src));
3171 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01003172 src.function_name = "link";
3173 dst.function_name = "link";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003174 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3175 path_converter, &src,
3176 path_converter, &dst,
3177 dir_fd_converter, &src_dir_fd,
3178 dir_fd_converter, &dst_dir_fd,
3179 &follow_symlinks))
3180 return NULL;
3181
3182#ifndef HAVE_LINKAT
3183 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3184 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3185 goto exit;
3186 }
3187#endif
3188
3189 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3190 PyErr_SetString(PyExc_NotImplementedError,
3191 "link: src and dst must be the same type");
3192 goto exit;
3193 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003194
Brian Curtin1b9df392010-11-24 20:24:31 +00003195#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003196 Py_BEGIN_ALLOW_THREADS
3197 if (src.wide)
3198 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3199 else
3200 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3201 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003202
Larry Hastings9cf065c2012-06-22 16:30:09 -07003203 if (!result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01003204 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003205 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003206 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003207#else
3208 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003209#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003210 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3211 (dst_dir_fd != DEFAULT_DIR_FD) ||
3212 (!follow_symlinks))
3213 result = linkat(src_dir_fd, src.narrow,
3214 dst_dir_fd, dst.narrow,
3215 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3216 else
3217#endif
3218 result = link(src.narrow, dst.narrow);
3219 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003220
Larry Hastings9cf065c2012-06-22 16:30:09 -07003221 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003222 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003223 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003224 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003225#endif
3226
3227 return_value = Py_None;
3228 Py_INCREF(Py_None);
3229
3230exit:
3231 path_cleanup(&src);
3232 path_cleanup(&dst);
3233 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003234}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003235#endif
3236
Brian Curtin1b9df392010-11-24 20:24:31 +00003237
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003238
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003239PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastingsfdaea062012-06-25 04:42:23 -07003240"listdir(path='.') -> list_of_filenames\n\n\
3241Return a list containing the names of the files in the directory.\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003242The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003243entries '.' and '..' even if they are present in the directory.\n\
3244\n\
Larry Hastingsfdaea062012-06-25 04:42:23 -07003245path can be specified as either str or bytes. If path is bytes,\n\
3246 the filenames returned will also be bytes; in all other circumstances\n\
3247 the filenames returned will be str.\n\
3248On some platforms, path may also be specified as an open file descriptor;\n\
3249 the file descriptor must refer to a directory.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003250 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003251
Barry Warsaw53699e91996-12-10 23:23:01 +00003252static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003253posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003254{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003255 path_t path;
3256 PyObject *list = NULL;
3257 static char *keywords[] = {"path", NULL};
3258 int fd = -1;
3259
3260#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3261 PyObject *v;
3262 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3263 BOOL result;
3264 WIN32_FIND_DATA FileData;
3265 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
3266 char *bufptr = namebuf;
3267 /* only claim to have space for MAX_PATH */
3268 Py_ssize_t len = sizeof(namebuf)-5;
3269 PyObject *po = NULL;
3270 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003271#else
3272 PyObject *v;
3273 DIR *dirp = NULL;
3274 struct dirent *ep;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003275 int return_str; /* if false, return bytes */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003276#endif
3277
3278 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003279 path.function_name = "listdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003280 path.nullable = 1;
3281#ifdef HAVE_FDOPENDIR
3282 path.allow_fd = 1;
3283 path.fd = -1;
3284#endif
3285 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3286 path_converter, &path
3287 ))
3288 return NULL;
3289
Victor Stinner8c62be82010-05-06 00:08:46 +00003290 /* XXX Should redo this putting the (now four) versions of opendir
3291 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003292#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003293 if (!path.narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003294 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003295 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003296
Larry Hastings9cf065c2012-06-22 16:30:09 -07003297 if (!path.wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003298 po_wchars = L".";
3299 len = 1;
3300 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003301 po_wchars = path.wide;
3302 len = wcslen(path.wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003303 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003304 /* The +5 is so we can append "\\*.*\0" */
Victor Stinner8c62be82010-05-06 00:08:46 +00003305 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
3306 if (!wnamebuf) {
3307 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003308 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003309 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003310 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003311 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003312 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00003313 if (wch != L'/' && wch != L'\\' && wch != L':')
3314 wnamebuf[len++] = L'\\';
3315 wcscpy(wnamebuf + len, L"*.*");
3316 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003317 if ((list = PyList_New(0)) == NULL) {
3318 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003319 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003320 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003321 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003322 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003323 if (hFindFile == INVALID_HANDLE_VALUE) {
3324 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003325 if (error == ERROR_FILE_NOT_FOUND)
3326 goto exit;
3327 Py_DECREF(list);
Victor Stinnerb024e842012-10-31 22:24:06 +01003328 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003329 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003330 }
3331 do {
3332 /* Skip over . and .. */
3333 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3334 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003335 v = PyUnicode_FromWideChar(wFileData.cFileName,
3336 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003337 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003338 Py_DECREF(list);
3339 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003340 break;
3341 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003342 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003343 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003344 Py_DECREF(list);
3345 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003346 break;
3347 }
3348 Py_DECREF(v);
3349 }
3350 Py_BEGIN_ALLOW_THREADS
3351 result = FindNextFileW(hFindFile, &wFileData);
3352 Py_END_ALLOW_THREADS
3353 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3354 it got to the end of the directory. */
3355 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003356 Py_DECREF(list);
Victor Stinnerb024e842012-10-31 22:24:06 +01003357 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003358 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003359 }
3360 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003361
Larry Hastings9cf065c2012-06-22 16:30:09 -07003362 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003363 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003364 strcpy(namebuf, path.narrow);
3365 len = path.length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003366 if (len > 0) {
3367 char ch = namebuf[len-1];
3368 if (ch != SEP && ch != ALTSEP && ch != ':')
3369 namebuf[len++] = '/';
3370 strcpy(namebuf + len, "*.*");
3371 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003372
Larry Hastings9cf065c2012-06-22 16:30:09 -07003373 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003374 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003375
Antoine Pitroub73caab2010-08-09 23:39:31 +00003376 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003377 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003378 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003379 if (hFindFile == INVALID_HANDLE_VALUE) {
3380 int error = GetLastError();
3381 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003382 goto exit;
3383 Py_DECREF(list);
Victor Stinnerb024e842012-10-31 22:24:06 +01003384 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003385 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003386 }
3387 do {
3388 /* Skip over . and .. */
3389 if (strcmp(FileData.cFileName, ".") != 0 &&
3390 strcmp(FileData.cFileName, "..") != 0) {
3391 v = PyBytes_FromString(FileData.cFileName);
3392 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003393 Py_DECREF(list);
3394 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003395 break;
3396 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003397 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003398 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003399 Py_DECREF(list);
3400 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003401 break;
3402 }
3403 Py_DECREF(v);
3404 }
3405 Py_BEGIN_ALLOW_THREADS
3406 result = FindNextFile(hFindFile, &FileData);
3407 Py_END_ALLOW_THREADS
3408 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3409 it got to the end of the directory. */
3410 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003411 Py_DECREF(list);
Victor Stinnerb024e842012-10-31 22:24:06 +01003412 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003413 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003414 }
3415 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003416
Larry Hastings9cf065c2012-06-22 16:30:09 -07003417exit:
3418 if (hFindFile != INVALID_HANDLE_VALUE) {
3419 if (FindClose(hFindFile) == FALSE) {
3420 if (list != NULL) {
3421 Py_DECREF(list);
Victor Stinnerb024e842012-10-31 22:24:06 +01003422 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003423 }
3424 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003425 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003426 if (wnamebuf)
3427 free(wnamebuf);
3428 path_cleanup(&path);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003429
Larry Hastings9cf065c2012-06-22 16:30:09 -07003430 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003431
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003432#else
Just van Rossum96b1c902003-03-03 17:32:15 +00003433
Victor Stinner8c62be82010-05-06 00:08:46 +00003434 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003435#ifdef HAVE_FDOPENDIR
3436 if (path.fd != -1) {
3437 /* closedir() closes the FD, so we duplicate it */
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003438 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003439 fd = dup(path.fd);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003440 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003441
3442 if (fd == -1) {
3443 list = posix_error();
3444 goto exit;
3445 }
3446
Larry Hastingsfdaea062012-06-25 04:42:23 -07003447 return_str = 1;
3448
Larry Hastings9cf065c2012-06-22 16:30:09 -07003449 Py_BEGIN_ALLOW_THREADS
3450 dirp = fdopendir(fd);
3451 Py_END_ALLOW_THREADS
3452 }
3453 else
3454#endif
3455 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003456 char *name;
3457 if (path.narrow) {
3458 name = path.narrow;
3459 /* only return bytes if they specified a bytes object */
3460 return_str = !(PyBytes_Check(path.object));
3461 }
3462 else {
3463 name = ".";
3464 return_str = 1;
3465 }
3466
Larry Hastings9cf065c2012-06-22 16:30:09 -07003467 Py_BEGIN_ALLOW_THREADS
3468 dirp = opendir(name);
3469 Py_END_ALLOW_THREADS
3470 }
3471
3472 if (dirp == NULL) {
Victor Stinner292c8352012-10-30 02:17:38 +01003473 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003474 goto exit;
3475 }
3476 if ((list = PyList_New(0)) == NULL) {
3477 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003478 }
3479 for (;;) {
3480 errno = 0;
3481 Py_BEGIN_ALLOW_THREADS
3482 ep = readdir(dirp);
3483 Py_END_ALLOW_THREADS
3484 if (ep == NULL) {
3485 if (errno == 0) {
3486 break;
3487 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003488 Py_DECREF(list);
Victor Stinner292c8352012-10-30 02:17:38 +01003489 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003490 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003491 }
3492 }
3493 if (ep->d_name[0] == '.' &&
3494 (NAMLEN(ep) == 1 ||
3495 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3496 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003497 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003498 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3499 else
3500 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003501 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003502 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003503 break;
3504 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003505 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003506 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003507 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003508 break;
3509 }
3510 Py_DECREF(v);
3511 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003512
Larry Hastings9cf065c2012-06-22 16:30:09 -07003513exit:
3514 if (dirp != NULL) {
3515 Py_BEGIN_ALLOW_THREADS
3516 if (fd > -1)
3517 rewinddir(dirp);
3518 closedir(dirp);
3519 Py_END_ALLOW_THREADS
3520 }
3521
3522 path_cleanup(&path);
3523
3524 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003525
Tim Peters0bb44a42000-09-15 07:44:49 +00003526#endif /* which OS */
3527} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003528
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003529#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003530/* A helper function for abspath on win32 */
3531static PyObject *
3532posix__getfullpathname(PyObject *self, PyObject *args)
3533{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003534 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003535 char outbuf[MAX_PATH*2];
3536 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003537 PyObject *po;
3538
3539 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3540 {
3541 wchar_t *wpath;
3542 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3543 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003544 DWORD result;
3545 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003546
3547 wpath = PyUnicode_AsUnicode(po);
3548 if (wpath == NULL)
3549 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003550 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003551 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003552 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003553 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003554 woutbufp = malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003555 if (!woutbufp)
3556 return PyErr_NoMemory();
3557 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3558 }
3559 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003560 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003561 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003562 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003563 if (woutbufp != woutbuf)
3564 free(woutbufp);
3565 return v;
3566 }
3567 /* Drop the argument parsing error as narrow strings
3568 are also valid. */
3569 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003570
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003571 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3572 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003573 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003574 if (win32_warn_bytes_api())
3575 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003576 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003577 outbuf, &temp)) {
3578 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003579 return NULL;
3580 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003581 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3582 return PyUnicode_Decode(outbuf, strlen(outbuf),
3583 Py_FileSystemDefaultEncoding, NULL);
3584 }
3585 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003586} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003587
Brian Curtind25aef52011-06-13 15:16:04 -05003588
Brian Curtinf5e76d02010-11-24 13:14:05 +00003589
Brian Curtind40e6f72010-07-08 21:39:08 +00003590/* A helper function for samepath on windows */
3591static PyObject *
3592posix__getfinalpathname(PyObject *self, PyObject *args)
3593{
3594 HANDLE hFile;
3595 int buf_size;
3596 wchar_t *target_path;
3597 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003598 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003599 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003600
Victor Stinnereb5657a2011-09-30 01:44:27 +02003601 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003602 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003603 path = PyUnicode_AsUnicode(po);
3604 if (path == NULL)
3605 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003606
3607 if(!check_GetFinalPathNameByHandle()) {
3608 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3609 NotImplementedError. */
3610 return PyErr_Format(PyExc_NotImplementedError,
3611 "GetFinalPathNameByHandle not available on this platform");
3612 }
3613
3614 hFile = CreateFileW(
3615 path,
3616 0, /* desired access */
3617 0, /* share mode */
3618 NULL, /* security attributes */
3619 OPEN_EXISTING,
3620 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3621 FILE_FLAG_BACKUP_SEMANTICS,
3622 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003623
Victor Stinnereb5657a2011-09-30 01:44:27 +02003624 if(hFile == INVALID_HANDLE_VALUE)
3625 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003626
3627 /* We have a good handle to the target, use it to determine the
3628 target path name. */
3629 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3630
3631 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003632 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003633
3634 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
3635 if(!target_path)
3636 return PyErr_NoMemory();
3637
3638 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3639 buf_size, VOLUME_NAME_DOS);
3640 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003641 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003642
3643 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003644 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003645
3646 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003647 result = PyUnicode_FromWideChar(target_path, result_length);
Brian Curtind40e6f72010-07-08 21:39:08 +00003648 free(target_path);
3649 return result;
3650
3651} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003652
Brian Curtin95d028f2011-06-09 09:10:38 -05003653PyDoc_STRVAR(posix__isdir__doc__,
3654"Return true if the pathname refers to an existing directory.");
3655
Brian Curtin9c669cc2011-06-08 18:17:18 -05003656static PyObject *
3657posix__isdir(PyObject *self, PyObject *args)
3658{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003659 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003660 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003661 DWORD attributes;
3662
3663 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003664 wchar_t *wpath = PyUnicode_AsUnicode(po);
3665 if (wpath == NULL)
3666 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003667
3668 attributes = GetFileAttributesW(wpath);
3669 if (attributes == INVALID_FILE_ATTRIBUTES)
3670 Py_RETURN_FALSE;
3671 goto check;
3672 }
3673 /* Drop the argument parsing error as narrow strings
3674 are also valid. */
3675 PyErr_Clear();
3676
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003677 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003678 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003679 if (win32_warn_bytes_api())
3680 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003681 attributes = GetFileAttributesA(path);
3682 if (attributes == INVALID_FILE_ATTRIBUTES)
3683 Py_RETURN_FALSE;
3684
3685check:
3686 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3687 Py_RETURN_TRUE;
3688 else
3689 Py_RETURN_FALSE;
3690}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003691#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003692
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003693PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003694"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3695Create a directory.\n\
3696\n\
3697If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3698 and path should be relative; path will then be relative to that directory.\n\
3699dir_fd may not be implemented on your platform.\n\
3700 If it is unavailable, using it will raise a NotImplementedError.\n\
3701\n\
3702The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003703
Barry Warsaw53699e91996-12-10 23:23:01 +00003704static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003705posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003706{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003707 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003708 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003709 int dir_fd = DEFAULT_DIR_FD;
3710 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
3711 PyObject *return_value = NULL;
3712 int result;
3713
3714 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003715 path.function_name = "mkdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003716 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
3717 path_converter, &path, &mode,
3718#ifdef HAVE_MKDIRAT
3719 dir_fd_converter, &dir_fd
3720#else
3721 dir_fd_unavailable, &dir_fd
3722#endif
3723 ))
3724 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003725
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003726#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003727 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003728 if (path.wide)
3729 result = CreateDirectoryW(path.wide, NULL);
3730 else
3731 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003732 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003733
Larry Hastings9cf065c2012-06-22 16:30:09 -07003734 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003735 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003736 goto exit;
3737 }
3738#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003739 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003740#if HAVE_MKDIRAT
3741 if (dir_fd != DEFAULT_DIR_FD)
3742 result = mkdirat(dir_fd, path.narrow, mode);
3743 else
3744#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003745#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003746 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003747#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003748 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003749#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003750 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003751 if (result < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01003752 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003753 goto exit;
3754 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00003755#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003756 return_value = Py_None;
3757 Py_INCREF(Py_None);
3758exit:
3759 path_cleanup(&path);
3760 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003761}
3762
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003763
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003764/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3765#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003766#include <sys/resource.h>
3767#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003768
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003769
3770#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003771PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003772"nice(inc) -> new_priority\n\n\
3773Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003774
Barry Warsaw53699e91996-12-10 23:23:01 +00003775static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003776posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00003777{
Victor Stinner8c62be82010-05-06 00:08:46 +00003778 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00003779
Victor Stinner8c62be82010-05-06 00:08:46 +00003780 if (!PyArg_ParseTuple(args, "i:nice", &increment))
3781 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003782
Victor Stinner8c62be82010-05-06 00:08:46 +00003783 /* There are two flavours of 'nice': one that returns the new
3784 priority (as required by almost all standards out there) and the
3785 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3786 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003787
Victor Stinner8c62be82010-05-06 00:08:46 +00003788 If we are of the nice family that returns the new priority, we
3789 need to clear errno before the call, and check if errno is filled
3790 before calling posix_error() on a returnvalue of -1, because the
3791 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003792
Victor Stinner8c62be82010-05-06 00:08:46 +00003793 errno = 0;
3794 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003795#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003796 if (value == 0)
3797 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003798#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003799 if (value == -1 && errno != 0)
3800 /* either nice() or getpriority() returned an error */
3801 return posix_error();
3802 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003803}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003804#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003805
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003806
3807#ifdef HAVE_GETPRIORITY
3808PyDoc_STRVAR(posix_getpriority__doc__,
3809"getpriority(which, who) -> current_priority\n\n\
3810Get program scheduling priority.");
3811
3812static PyObject *
3813posix_getpriority(PyObject *self, PyObject *args)
3814{
3815 int which, who, retval;
3816
3817 if (!PyArg_ParseTuple(args, "ii", &which, &who))
3818 return NULL;
3819 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003820 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003821 if (errno != 0)
3822 return posix_error();
3823 return PyLong_FromLong((long)retval);
3824}
3825#endif /* HAVE_GETPRIORITY */
3826
3827
3828#ifdef HAVE_SETPRIORITY
3829PyDoc_STRVAR(posix_setpriority__doc__,
3830"setpriority(which, who, prio) -> None\n\n\
3831Set program scheduling priority.");
3832
3833static PyObject *
3834posix_setpriority(PyObject *self, PyObject *args)
3835{
3836 int which, who, prio, retval;
3837
3838 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
3839 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003840 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003841 if (retval == -1)
3842 return posix_error();
3843 Py_RETURN_NONE;
3844}
3845#endif /* HAVE_SETPRIORITY */
3846
3847
Barry Warsaw53699e91996-12-10 23:23:01 +00003848static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003849internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003850{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003851 char *function_name = is_replace ? "replace" : "rename";
3852 path_t src;
3853 path_t dst;
3854 int src_dir_fd = DEFAULT_DIR_FD;
3855 int dst_dir_fd = DEFAULT_DIR_FD;
3856 int dir_fd_specified;
3857 PyObject *return_value = NULL;
3858 char format[24];
3859 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
3860
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003861#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003862 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003863 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003864#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003865 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003866#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003867
3868 memset(&src, 0, sizeof(src));
3869 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01003870 src.function_name = function_name;
3871 dst.function_name = function_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003872 strcpy(format, "O&O&|$O&O&:");
3873 strcat(format, function_name);
3874 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
3875 path_converter, &src,
3876 path_converter, &dst,
3877 dir_fd_converter, &src_dir_fd,
3878 dir_fd_converter, &dst_dir_fd))
3879 return NULL;
3880
3881 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
3882 (dst_dir_fd != DEFAULT_DIR_FD);
3883#ifndef HAVE_RENAMEAT
3884 if (dir_fd_specified) {
3885 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
3886 goto exit;
3887 }
3888#endif
3889
3890 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3891 PyErr_Format(PyExc_ValueError,
3892 "%s: src and dst must be the same type", function_name);
3893 goto exit;
3894 }
3895
3896#ifdef MS_WINDOWS
3897 Py_BEGIN_ALLOW_THREADS
3898 if (src.wide)
3899 result = MoveFileExW(src.wide, dst.wide, flags);
3900 else
3901 result = MoveFileExA(src.narrow, dst.narrow, flags);
3902 Py_END_ALLOW_THREADS
3903
3904 if (!result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01003905 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003906 goto exit;
3907 }
3908
3909#else
3910 Py_BEGIN_ALLOW_THREADS
3911#ifdef HAVE_RENAMEAT
3912 if (dir_fd_specified)
3913 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
3914 else
3915#endif
3916 result = rename(src.narrow, dst.narrow);
3917 Py_END_ALLOW_THREADS
3918
3919 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003920 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003921 goto exit;
3922 }
3923#endif
3924
3925 Py_INCREF(Py_None);
3926 return_value = Py_None;
3927exit:
3928 path_cleanup(&src);
3929 path_cleanup(&dst);
3930 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003931}
3932
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003933PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003934"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
3935Rename a file or directory.\n\
3936\n\
3937If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3938 descriptor open to a directory, and the respective path string (src or dst)\n\
3939 should be relative; the path will then be relative to that directory.\n\
3940src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
3941 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003942
3943static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003944posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003945{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003946 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003947}
3948
3949PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003950"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
3951Rename a file or directory, overwriting the destination.\n\
3952\n\
3953If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3954 descriptor open to a directory, and the respective path string (src or dst)\n\
3955 should be relative; the path will then be relative to that directory.\n\
3956src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
3957 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003958
3959static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003960posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003961{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003962 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003963}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003964
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003965PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003966"rmdir(path, *, dir_fd=None)\n\n\
3967Remove a directory.\n\
3968\n\
3969If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3970 and path should be relative; path will then be relative to that directory.\n\
3971dir_fd may not be implemented on your platform.\n\
3972 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003973
Barry Warsaw53699e91996-12-10 23:23:01 +00003974static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003975posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003976{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003977 path_t path;
3978 int dir_fd = DEFAULT_DIR_FD;
3979 static char *keywords[] = {"path", "dir_fd", NULL};
3980 int result;
3981 PyObject *return_value = NULL;
3982
3983 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003984 path.function_name = "rmdir";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003985 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
3986 path_converter, &path,
3987#ifdef HAVE_UNLINKAT
3988 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003989#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003990 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003991#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003992 ))
3993 return NULL;
3994
3995 Py_BEGIN_ALLOW_THREADS
3996#ifdef MS_WINDOWS
3997 if (path.wide)
3998 result = RemoveDirectoryW(path.wide);
3999 else
4000 result = RemoveDirectoryA(path.narrow);
4001 result = !result; /* Windows, success=1, UNIX, success=0 */
4002#else
4003#ifdef HAVE_UNLINKAT
4004 if (dir_fd != DEFAULT_DIR_FD)
4005 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
4006 else
4007#endif
4008 result = rmdir(path.narrow);
4009#endif
4010 Py_END_ALLOW_THREADS
4011
4012 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004013 return_value = path_error(&path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004014 goto exit;
4015 }
4016
4017 return_value = Py_None;
4018 Py_INCREF(Py_None);
4019
4020exit:
4021 path_cleanup(&path);
4022 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004023}
4024
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004025
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004026#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004027PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004028"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004029Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004030
Barry Warsaw53699e91996-12-10 23:23:01 +00004031static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004032posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004033{
Victor Stinner8c62be82010-05-06 00:08:46 +00004034 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004035#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004036 wchar_t *command;
4037 if (!PyArg_ParseTuple(args, "u:system", &command))
4038 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004039
Victor Stinner8c62be82010-05-06 00:08:46 +00004040 Py_BEGIN_ALLOW_THREADS
4041 sts = _wsystem(command);
4042 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004043#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004044 PyObject *command_obj;
4045 char *command;
4046 if (!PyArg_ParseTuple(args, "O&:system",
4047 PyUnicode_FSConverter, &command_obj))
4048 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004049
Victor Stinner8c62be82010-05-06 00:08:46 +00004050 command = PyBytes_AsString(command_obj);
4051 Py_BEGIN_ALLOW_THREADS
4052 sts = system(command);
4053 Py_END_ALLOW_THREADS
4054 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004055#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004056 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004057}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004058#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004059
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004060
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004061PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004062"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004063Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004064
Barry Warsaw53699e91996-12-10 23:23:01 +00004065static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004066posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004067{
Victor Stinner8c62be82010-05-06 00:08:46 +00004068 int i;
4069 if (!PyArg_ParseTuple(args, "i:umask", &i))
4070 return NULL;
4071 i = (int)umask(i);
4072 if (i < 0)
4073 return posix_error();
4074 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004075}
4076
Brian Curtind40e6f72010-07-08 21:39:08 +00004077#ifdef MS_WINDOWS
4078
4079/* override the default DeleteFileW behavior so that directory
4080symlinks can be removed with this function, the same as with
4081Unix symlinks */
4082BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4083{
4084 WIN32_FILE_ATTRIBUTE_DATA info;
4085 WIN32_FIND_DATAW find_data;
4086 HANDLE find_data_handle;
4087 int is_directory = 0;
4088 int is_link = 0;
4089
4090 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4091 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004092
Brian Curtind40e6f72010-07-08 21:39:08 +00004093 /* Get WIN32_FIND_DATA structure for the path to determine if
4094 it is a symlink */
4095 if(is_directory &&
4096 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4097 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4098
4099 if(find_data_handle != INVALID_HANDLE_VALUE) {
4100 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4101 FindClose(find_data_handle);
4102 }
4103 }
4104 }
4105
4106 if (is_directory && is_link)
4107 return RemoveDirectoryW(lpFileName);
4108
4109 return DeleteFileW(lpFileName);
4110}
4111#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004112
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004113PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004114"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004115Remove a file (same as remove()).\n\
4116\n\
4117If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4118 and path should be relative; path will then be relative to that directory.\n\
4119dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004120 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004121
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004122PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004123"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004124Remove a file (same as unlink()).\n\
4125\n\
4126If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4127 and path should be relative; path will then be relative to that directory.\n\
4128dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004129 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004130
Barry Warsaw53699e91996-12-10 23:23:01 +00004131static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004132posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004133{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004134 path_t path;
4135 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004136 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004137 int result;
4138 PyObject *return_value = NULL;
4139
4140 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004141 path.function_name = "unlink";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004142 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004143 path_converter, &path,
4144#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004145 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004146#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004147 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004148#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004149 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004150 return NULL;
4151
4152 Py_BEGIN_ALLOW_THREADS
4153#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004154 if (path.wide)
4155 result = Py_DeleteFileW(path.wide);
4156 else
4157 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004158 result = !result; /* Windows, success=1, UNIX, success=0 */
4159#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004160#ifdef HAVE_UNLINKAT
4161 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004162 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004163 else
4164#endif /* HAVE_UNLINKAT */
4165 result = unlink(path.narrow);
4166#endif
4167 Py_END_ALLOW_THREADS
4168
4169 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004170 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004171 goto exit;
4172 }
4173
4174 return_value = Py_None;
4175 Py_INCREF(Py_None);
4176
4177exit:
4178 path_cleanup(&path);
4179 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004180}
4181
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004182
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004183PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004184"uname() -> uname_result\n\n\
4185Return an object identifying the current operating system.\n\
4186The object behaves like a named tuple with the following fields:\n\
4187 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004188
Larry Hastings605a62d2012-06-24 04:33:36 -07004189static PyStructSequence_Field uname_result_fields[] = {
4190 {"sysname", "operating system name"},
4191 {"nodename", "name of machine on network (implementation-defined)"},
4192 {"release", "operating system release"},
4193 {"version", "operating system version"},
4194 {"machine", "hardware identifier"},
4195 {NULL}
4196};
4197
4198PyDoc_STRVAR(uname_result__doc__,
4199"uname_result: Result from os.uname().\n\n\
4200This object may be accessed either as a tuple of\n\
4201 (sysname, nodename, release, version, machine),\n\
4202or via the attributes sysname, nodename, release, version, and machine.\n\
4203\n\
4204See os.uname for more information.");
4205
4206static PyStructSequence_Desc uname_result_desc = {
4207 "uname_result", /* name */
4208 uname_result__doc__, /* doc */
4209 uname_result_fields,
4210 5
4211};
4212
4213static PyTypeObject UnameResultType;
4214
4215
4216#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004217static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004218posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004219{
Victor Stinner8c62be82010-05-06 00:08:46 +00004220 struct utsname u;
4221 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004222 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004223
Victor Stinner8c62be82010-05-06 00:08:46 +00004224 Py_BEGIN_ALLOW_THREADS
4225 res = uname(&u);
4226 Py_END_ALLOW_THREADS
4227 if (res < 0)
4228 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004229
4230 value = PyStructSequence_New(&UnameResultType);
4231 if (value == NULL)
4232 return NULL;
4233
4234#define SET(i, field) \
4235 { \
4236 PyObject *o = PyUnicode_DecodeASCII(field, strlen(field), NULL); \
4237 if (!o) { \
4238 Py_DECREF(value); \
4239 return NULL; \
4240 } \
4241 PyStructSequence_SET_ITEM(value, i, o); \
4242 } \
4243
4244 SET(0, u.sysname);
4245 SET(1, u.nodename);
4246 SET(2, u.release);
4247 SET(3, u.version);
4248 SET(4, u.machine);
4249
4250#undef SET
4251
4252 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004253}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004254#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004255
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004256
Larry Hastings9cf065c2012-06-22 16:30:09 -07004257PyDoc_STRVAR(posix_utime__doc__,
4258"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4259Set the access and modified time of path.\n\
4260\n\
4261path may always be specified as a string.\n\
4262On some platforms, path may also be specified as an open file descriptor.\n\
4263 If this functionality is unavailable, using it raises an exception.\n\
4264\n\
4265If times is not None, it must be a tuple (atime, mtime);\n\
4266 atime and mtime should be expressed as float seconds since the epoch.\n\
4267If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4268 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4269 since the epoch.\n\
4270If both times and ns are None, utime uses the current time.\n\
4271Specifying tuples for both times and ns is an error.\n\
4272\n\
4273If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4274 and path should be relative; path will then be relative to that directory.\n\
4275If follow_symlinks is False, and the last element of the path is a symbolic\n\
4276 link, utime will modify the symbolic link itself instead of the file the\n\
4277 link points to.\n\
4278It is an error to use dir_fd or follow_symlinks when specifying path\n\
4279 as an open file descriptor.\n\
4280dir_fd and follow_symlinks may not be available on your platform.\n\
4281 If they are unavailable, using them will raise a NotImplementedError.");
4282
4283typedef struct {
4284 int now;
4285 time_t atime_s;
4286 long atime_ns;
4287 time_t mtime_s;
4288 long mtime_ns;
4289} utime_t;
4290
4291/*
4292 * these macros assume that "utime" is a pointer to a utime_t
4293 * they also intentionally leak the declaration of a pointer named "time"
4294 */
4295#define UTIME_TO_TIMESPEC \
4296 struct timespec ts[2]; \
4297 struct timespec *time; \
4298 if (utime->now) \
4299 time = NULL; \
4300 else { \
4301 ts[0].tv_sec = utime->atime_s; \
4302 ts[0].tv_nsec = utime->atime_ns; \
4303 ts[1].tv_sec = utime->mtime_s; \
4304 ts[1].tv_nsec = utime->mtime_ns; \
4305 time = ts; \
4306 } \
4307
4308#define UTIME_TO_TIMEVAL \
4309 struct timeval tv[2]; \
4310 struct timeval *time; \
4311 if (utime->now) \
4312 time = NULL; \
4313 else { \
4314 tv[0].tv_sec = utime->atime_s; \
4315 tv[0].tv_usec = utime->atime_ns / 1000; \
4316 tv[1].tv_sec = utime->mtime_s; \
4317 tv[1].tv_usec = utime->mtime_ns / 1000; \
4318 time = tv; \
4319 } \
4320
4321#define UTIME_TO_UTIMBUF \
4322 struct utimbuf u[2]; \
4323 struct utimbuf *time; \
4324 if (utime->now) \
4325 time = NULL; \
4326 else { \
4327 u.actime = utime->atime_s; \
4328 u.modtime = utime->mtime_s; \
4329 time = u; \
4330 }
4331
4332#define UTIME_TO_TIME_T \
4333 time_t timet[2]; \
4334 struct timet time; \
4335 if (utime->now) \
4336 time = NULL; \
4337 else { \
4338 timet[0] = utime->atime_s; \
4339 timet[1] = utime->mtime_s; \
4340 time = &timet; \
4341 } \
4342
4343
4344#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4345
4346#if UTIME_HAVE_DIR_FD
4347
4348static int
4349utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4350{
4351#ifdef HAVE_UTIMENSAT
4352 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4353 UTIME_TO_TIMESPEC;
4354 return utimensat(dir_fd, path, time, flags);
4355#elif defined(HAVE_FUTIMESAT)
4356 UTIME_TO_TIMEVAL;
4357 /*
4358 * follow_symlinks will never be false here;
4359 * we only allow !follow_symlinks and dir_fd together
4360 * if we have utimensat()
4361 */
4362 assert(follow_symlinks);
4363 return futimesat(dir_fd, path, time);
4364#endif
4365}
4366
4367#endif
4368
4369#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4370
4371#if UTIME_HAVE_FD
4372
4373static int
4374utime_fd(utime_t *utime, int fd)
4375{
4376#ifdef HAVE_FUTIMENS
4377 UTIME_TO_TIMESPEC;
4378 return futimens(fd, time);
4379#else
4380 UTIME_TO_TIMEVAL;
4381 return futimes(fd, time);
4382#endif
4383}
4384
4385#endif
4386
4387
4388#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4389 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4390
4391#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4392
4393static int
4394utime_nofollow_symlinks(utime_t *utime, char *path)
4395{
4396#ifdef HAVE_UTIMENSAT
4397 UTIME_TO_TIMESPEC;
4398 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4399#else
4400 UTIME_TO_TIMEVAL;
4401 return lutimes(path, time);
4402#endif
4403}
4404
4405#endif
4406
4407#ifndef MS_WINDOWS
4408
4409static int
4410utime_default(utime_t *utime, char *path)
4411{
4412#ifdef HAVE_UTIMENSAT
4413 UTIME_TO_TIMESPEC;
4414 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4415#elif defined(HAVE_UTIMES)
4416 UTIME_TO_TIMEVAL;
4417 return utimes(path, time);
4418#elif defined(HAVE_UTIME_H)
4419 UTIME_TO_UTIMBUF;
4420 return utime(path, time);
4421#else
4422 UTIME_TO_TIME_T;
4423 return utime(path, time);
4424#endif
4425}
4426
4427#endif
4428
Larry Hastings76ad59b2012-05-03 00:30:07 -07004429static int
4430split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4431{
4432 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004433 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004434 divmod = PyNumber_Divmod(py_long, billion);
4435 if (!divmod)
4436 goto exit;
4437 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4438 if ((*s == -1) && PyErr_Occurred())
4439 goto exit;
4440 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004441 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004442 goto exit;
4443
4444 result = 1;
4445exit:
4446 Py_XDECREF(divmod);
4447 return result;
4448}
4449
Larry Hastings9cf065c2012-06-22 16:30:09 -07004450static PyObject *
4451posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004452{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004453 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004454 PyObject *times = NULL;
4455 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004456 int dir_fd = DEFAULT_DIR_FD;
4457 int follow_symlinks = 1;
4458 char *keywords[] = {"path", "times", "ns", "dir_fd",
4459 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004460
Larry Hastings9cf065c2012-06-22 16:30:09 -07004461 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004462
Larry Hastings9cf065c2012-06-22 16:30:09 -07004463#ifdef MS_WINDOWS
4464 HANDLE hFile;
4465 FILETIME atime, mtime;
4466#else
4467 int result;
4468#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004469
Larry Hastings9cf065c2012-06-22 16:30:09 -07004470 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004471
Larry Hastings9cf065c2012-06-22 16:30:09 -07004472 memset(&path, 0, sizeof(path));
Victor Stinnerb024e842012-10-31 22:24:06 +01004473 path.function_name = "utime";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004474#if UTIME_HAVE_FD
4475 path.allow_fd = 1;
4476#endif
4477 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4478 "O&|O$OO&p:utime", keywords,
4479 path_converter, &path,
4480 &times, &ns,
4481#if UTIME_HAVE_DIR_FD
4482 dir_fd_converter, &dir_fd,
4483#else
4484 dir_fd_unavailable, &dir_fd,
4485#endif
4486 &follow_symlinks
4487 ))
4488 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004489
Larry Hastings9cf065c2012-06-22 16:30:09 -07004490 if (times && (times != Py_None) && ns) {
4491 PyErr_SetString(PyExc_ValueError,
4492 "utime: you may specify either 'times'"
4493 " or 'ns' but not both");
4494 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004495 }
4496
4497 if (times && (times != Py_None)) {
4498 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004499 PyErr_SetString(PyExc_TypeError,
4500 "utime: 'times' must be either"
4501 " a tuple of two ints or None");
4502 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004503 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004504 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004505 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004506 &utime.atime_s, &utime.atime_ns) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004507 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004508 &utime.mtime_s, &utime.mtime_ns) == -1) {
4509 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004510 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004511 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004512 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004513 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004514 PyErr_SetString(PyExc_TypeError,
4515 "utime: 'ns' must be a tuple of two ints");
4516 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004517 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004518 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004519 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004520 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004521 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004522 &utime.mtime_s, &utime.mtime_ns)) {
4523 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004524 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004525 }
4526 else {
4527 /* times and ns are both None/unspecified. use "now". */
4528 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004529 }
4530
Larry Hastings9cf065c2012-06-22 16:30:09 -07004531#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4532 if (follow_symlinks_specified("utime", follow_symlinks))
4533 goto exit;
4534#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004535
Larry Hastings9cf065c2012-06-22 16:30:09 -07004536 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4537 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4538 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4539 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004540
Larry Hastings9cf065c2012-06-22 16:30:09 -07004541#if !defined(HAVE_UTIMENSAT)
4542 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004543 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004544 "utime: cannot use dir_fd and follow_symlinks "
4545 "together on this platform");
4546 goto exit;
4547 }
4548#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004549
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004550#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004551 Py_BEGIN_ALLOW_THREADS
4552 if (path.wide)
4553 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004554 NULL, OPEN_EXISTING,
4555 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004556 else
4557 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004558 NULL, OPEN_EXISTING,
4559 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004560 Py_END_ALLOW_THREADS
4561 if (hFile == INVALID_HANDLE_VALUE) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004562 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004563 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004564 }
4565
Larry Hastings9cf065c2012-06-22 16:30:09 -07004566 if (utime.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004567 SYSTEMTIME now;
4568 GetSystemTime(&now);
4569 if (!SystemTimeToFileTime(&now, &mtime) ||
4570 !SystemTimeToFileTime(&now, &atime)) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004571 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004572 goto exit;
Stefan Krah0e803b32010-11-26 16:16:47 +00004573 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004574 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004575 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004576 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4577 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004578 }
4579 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4580 /* Avoid putting the file name into the error here,
4581 as that may confuse the user into believing that
4582 something is wrong with the file, when it also
4583 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004584 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004585 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004586 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004587#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004588 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004589
Larry Hastings9cf065c2012-06-22 16:30:09 -07004590#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4591 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4592 result = utime_nofollow_symlinks(&utime, path.narrow);
4593 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004594#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004595
4596#if UTIME_HAVE_DIR_FD
4597 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4598 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4599 else
4600#endif
4601
4602#if UTIME_HAVE_FD
4603 if (path.fd != -1)
4604 result = utime_fd(&utime, path.fd);
4605 else
4606#endif
4607
4608 result = utime_default(&utime, path.narrow);
4609
4610 Py_END_ALLOW_THREADS
4611
4612 if (result < 0) {
4613 /* see previous comment about not putting filename in error here */
4614 return_value = posix_error();
4615 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004616 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004617
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004618#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004619
4620 Py_INCREF(Py_None);
4621 return_value = Py_None;
4622
4623exit:
4624 path_cleanup(&path);
4625#ifdef MS_WINDOWS
4626 if (hFile != INVALID_HANDLE_VALUE)
4627 CloseHandle(hFile);
4628#endif
4629 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004630}
4631
Guido van Rossum3b066191991-06-04 19:40:25 +00004632/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004633
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004634PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004635"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004636Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004637
Barry Warsaw53699e91996-12-10 23:23:01 +00004638static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004639posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004640{
Victor Stinner8c62be82010-05-06 00:08:46 +00004641 int sts;
4642 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
4643 return NULL;
4644 _exit(sts);
4645 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004646}
4647
Martin v. Löwis114619e2002-10-07 06:44:21 +00004648#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4649static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004650free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004651{
Victor Stinner8c62be82010-05-06 00:08:46 +00004652 Py_ssize_t i;
4653 for (i = 0; i < count; i++)
4654 PyMem_Free(array[i]);
4655 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004656}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004657
Antoine Pitrou69f71142009-05-24 21:25:49 +00004658static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004659int fsconvert_strdup(PyObject *o, char**out)
4660{
Victor Stinner8c62be82010-05-06 00:08:46 +00004661 PyObject *bytes;
4662 Py_ssize_t size;
4663 if (!PyUnicode_FSConverter(o, &bytes))
4664 return 0;
4665 size = PyBytes_GET_SIZE(bytes);
4666 *out = PyMem_Malloc(size+1);
4667 if (!*out)
4668 return 0;
4669 memcpy(*out, PyBytes_AsString(bytes), size+1);
4670 Py_DECREF(bytes);
4671 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004672}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004673#endif
4674
Ross Lagerwall7807c352011-03-17 20:20:30 +02004675#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004676static char**
4677parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4678{
Victor Stinner8c62be82010-05-06 00:08:46 +00004679 char **envlist;
4680 Py_ssize_t i, pos, envc;
4681 PyObject *keys=NULL, *vals=NULL;
4682 PyObject *key, *val, *key2, *val2;
4683 char *p, *k, *v;
4684 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004685
Victor Stinner8c62be82010-05-06 00:08:46 +00004686 i = PyMapping_Size(env);
4687 if (i < 0)
4688 return NULL;
4689 envlist = PyMem_NEW(char *, i + 1);
4690 if (envlist == NULL) {
4691 PyErr_NoMemory();
4692 return NULL;
4693 }
4694 envc = 0;
4695 keys = PyMapping_Keys(env);
4696 vals = PyMapping_Values(env);
4697 if (!keys || !vals)
4698 goto error;
4699 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4700 PyErr_Format(PyExc_TypeError,
4701 "env.keys() or env.values() is not a list");
4702 goto error;
4703 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004704
Victor Stinner8c62be82010-05-06 00:08:46 +00004705 for (pos = 0; pos < i; pos++) {
4706 key = PyList_GetItem(keys, pos);
4707 val = PyList_GetItem(vals, pos);
4708 if (!key || !val)
4709 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004710
Victor Stinner8c62be82010-05-06 00:08:46 +00004711 if (PyUnicode_FSConverter(key, &key2) == 0)
4712 goto error;
4713 if (PyUnicode_FSConverter(val, &val2) == 0) {
4714 Py_DECREF(key2);
4715 goto error;
4716 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004717
Victor Stinner8c62be82010-05-06 00:08:46 +00004718 k = PyBytes_AsString(key2);
4719 v = PyBytes_AsString(val2);
4720 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004721
Victor Stinner8c62be82010-05-06 00:08:46 +00004722 p = PyMem_NEW(char, len);
4723 if (p == NULL) {
4724 PyErr_NoMemory();
4725 Py_DECREF(key2);
4726 Py_DECREF(val2);
4727 goto error;
4728 }
4729 PyOS_snprintf(p, len, "%s=%s", k, v);
4730 envlist[envc++] = p;
4731 Py_DECREF(key2);
4732 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00004733 }
4734 Py_DECREF(vals);
4735 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004736
Victor Stinner8c62be82010-05-06 00:08:46 +00004737 envlist[envc] = 0;
4738 *envc_ptr = envc;
4739 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004740
4741error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004742 Py_XDECREF(keys);
4743 Py_XDECREF(vals);
4744 while (--envc >= 0)
4745 PyMem_DEL(envlist[envc]);
4746 PyMem_DEL(envlist);
4747 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004748}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004749
Ross Lagerwall7807c352011-03-17 20:20:30 +02004750static char**
4751parse_arglist(PyObject* argv, Py_ssize_t *argc)
4752{
4753 int i;
4754 char **argvlist = PyMem_NEW(char *, *argc+1);
4755 if (argvlist == NULL) {
4756 PyErr_NoMemory();
4757 return NULL;
4758 }
4759 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004760 PyObject* item = PySequence_ITEM(argv, i);
4761 if (item == NULL)
4762 goto fail;
4763 if (!fsconvert_strdup(item, &argvlist[i])) {
4764 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004765 goto fail;
4766 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004767 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004768 }
4769 argvlist[*argc] = NULL;
4770 return argvlist;
4771fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004772 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004773 free_string_array(argvlist, *argc);
4774 return NULL;
4775}
4776#endif
4777
4778#ifdef HAVE_EXECV
4779PyDoc_STRVAR(posix_execv__doc__,
4780"execv(path, args)\n\n\
4781Execute an executable path with arguments, replacing current process.\n\
4782\n\
4783 path: path of executable file\n\
4784 args: tuple or list of strings");
4785
4786static PyObject *
4787posix_execv(PyObject *self, PyObject *args)
4788{
4789 PyObject *opath;
4790 char *path;
4791 PyObject *argv;
4792 char **argvlist;
4793 Py_ssize_t argc;
4794
4795 /* execv has two arguments: (path, argv), where
4796 argv is a list or tuple of strings. */
4797
4798 if (!PyArg_ParseTuple(args, "O&O:execv",
4799 PyUnicode_FSConverter,
4800 &opath, &argv))
4801 return NULL;
4802 path = PyBytes_AsString(opath);
4803 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4804 PyErr_SetString(PyExc_TypeError,
4805 "execv() arg 2 must be a tuple or list");
4806 Py_DECREF(opath);
4807 return NULL;
4808 }
4809 argc = PySequence_Size(argv);
4810 if (argc < 1) {
4811 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
4812 Py_DECREF(opath);
4813 return NULL;
4814 }
4815
4816 argvlist = parse_arglist(argv, &argc);
4817 if (argvlist == NULL) {
4818 Py_DECREF(opath);
4819 return NULL;
4820 }
4821
4822 execv(path, argvlist);
4823
4824 /* If we get here it's definitely an error */
4825
4826 free_string_array(argvlist, argc);
4827 Py_DECREF(opath);
4828 return posix_error();
4829}
4830
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004831PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004832"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004833Execute a path with arguments and environment, replacing current process.\n\
4834\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004835 path: path of executable file\n\
4836 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004837 env: dictionary of strings mapping to strings\n\
4838\n\
4839On some platforms, you may specify an open file descriptor for path;\n\
4840 execve will execute the program the file descriptor is open to.\n\
4841 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004842
Barry Warsaw53699e91996-12-10 23:23:01 +00004843static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004844posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004845{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004846 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004847 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004848 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004849 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004850 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004851 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004852
Victor Stinner8c62be82010-05-06 00:08:46 +00004853 /* execve has three arguments: (path, argv, env), where
4854 argv is a list or tuple of strings and env is a dictionary
4855 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004856
Larry Hastings9cf065c2012-06-22 16:30:09 -07004857 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004858 path.function_name = "execve";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004859#ifdef HAVE_FEXECVE
4860 path.allow_fd = 1;
4861#endif
4862 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
4863 path_converter, &path,
4864 &argv, &env
4865 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00004866 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004867
Ross Lagerwall7807c352011-03-17 20:20:30 +02004868 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004869 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004870 "execve: argv must be a tuple or list");
4871 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004872 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004873 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00004874 if (!PyMapping_Check(env)) {
4875 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004876 "execve: environment must be a mapping object");
4877 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004878 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004879
Ross Lagerwall7807c352011-03-17 20:20:30 +02004880 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004881 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004882 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004883 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004884
Victor Stinner8c62be82010-05-06 00:08:46 +00004885 envlist = parse_envlist(env, &envc);
4886 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02004887 goto fail;
4888
Larry Hastings9cf065c2012-06-22 16:30:09 -07004889#ifdef HAVE_FEXECVE
4890 if (path.fd > -1)
4891 fexecve(path.fd, argvlist, envlist);
4892 else
4893#endif
4894 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004895
4896 /* If we get here it's definitely an error */
4897
Victor Stinner292c8352012-10-30 02:17:38 +01004898 path_error(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004899
4900 while (--envc >= 0)
4901 PyMem_DEL(envlist[envc]);
4902 PyMem_DEL(envlist);
4903 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004904 if (argvlist)
4905 free_string_array(argvlist, argc);
4906 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004907 return NULL;
4908}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004909#endif /* HAVE_EXECV */
4910
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004911
Guido van Rossuma1065681999-01-25 23:20:23 +00004912#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004913PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004914"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004915Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004916\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004917 mode: mode of process creation\n\
4918 path: path of executable file\n\
4919 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004920
4921static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004922posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004923{
Victor Stinner8c62be82010-05-06 00:08:46 +00004924 PyObject *opath;
4925 char *path;
4926 PyObject *argv;
4927 char **argvlist;
4928 int mode, i;
4929 Py_ssize_t argc;
4930 Py_intptr_t spawnval;
4931 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00004932
Victor Stinner8c62be82010-05-06 00:08:46 +00004933 /* spawnv has three arguments: (mode, path, argv), where
4934 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004935
Victor Stinner8c62be82010-05-06 00:08:46 +00004936 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
4937 PyUnicode_FSConverter,
4938 &opath, &argv))
4939 return NULL;
4940 path = PyBytes_AsString(opath);
4941 if (PyList_Check(argv)) {
4942 argc = PyList_Size(argv);
4943 getitem = PyList_GetItem;
4944 }
4945 else if (PyTuple_Check(argv)) {
4946 argc = PyTuple_Size(argv);
4947 getitem = PyTuple_GetItem;
4948 }
4949 else {
4950 PyErr_SetString(PyExc_TypeError,
4951 "spawnv() arg 2 must be a tuple or list");
4952 Py_DECREF(opath);
4953 return NULL;
4954 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004955
Victor Stinner8c62be82010-05-06 00:08:46 +00004956 argvlist = PyMem_NEW(char *, argc+1);
4957 if (argvlist == NULL) {
4958 Py_DECREF(opath);
4959 return PyErr_NoMemory();
4960 }
4961 for (i = 0; i < argc; i++) {
4962 if (!fsconvert_strdup((*getitem)(argv, i),
4963 &argvlist[i])) {
4964 free_string_array(argvlist, i);
4965 PyErr_SetString(
4966 PyExc_TypeError,
4967 "spawnv() arg 2 must contain only strings");
4968 Py_DECREF(opath);
4969 return NULL;
4970 }
4971 }
4972 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004973
Victor Stinner8c62be82010-05-06 00:08:46 +00004974 if (mode == _OLD_P_OVERLAY)
4975 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00004976
Victor Stinner8c62be82010-05-06 00:08:46 +00004977 Py_BEGIN_ALLOW_THREADS
4978 spawnval = _spawnv(mode, path, argvlist);
4979 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00004980
Victor Stinner8c62be82010-05-06 00:08:46 +00004981 free_string_array(argvlist, argc);
4982 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00004983
Victor Stinner8c62be82010-05-06 00:08:46 +00004984 if (spawnval == -1)
4985 return posix_error();
4986 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004987#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00004988 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004989#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004990 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004991#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00004992}
4993
4994
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004995PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004996"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004997Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004998\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004999 mode: mode of process creation\n\
5000 path: path of executable file\n\
5001 args: tuple or list of arguments\n\
5002 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005003
5004static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005005posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005006{
Victor Stinner8c62be82010-05-06 00:08:46 +00005007 PyObject *opath;
5008 char *path;
5009 PyObject *argv, *env;
5010 char **argvlist;
5011 char **envlist;
5012 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005013 int mode;
5014 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005015 Py_intptr_t spawnval;
5016 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5017 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005018
Victor Stinner8c62be82010-05-06 00:08:46 +00005019 /* spawnve has four arguments: (mode, path, argv, env), where
5020 argv is a list or tuple of strings and env is a dictionary
5021 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005022
Victor Stinner8c62be82010-05-06 00:08:46 +00005023 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5024 PyUnicode_FSConverter,
5025 &opath, &argv, &env))
5026 return NULL;
5027 path = PyBytes_AsString(opath);
5028 if (PyList_Check(argv)) {
5029 argc = PyList_Size(argv);
5030 getitem = PyList_GetItem;
5031 }
5032 else if (PyTuple_Check(argv)) {
5033 argc = PyTuple_Size(argv);
5034 getitem = PyTuple_GetItem;
5035 }
5036 else {
5037 PyErr_SetString(PyExc_TypeError,
5038 "spawnve() arg 2 must be a tuple or list");
5039 goto fail_0;
5040 }
5041 if (!PyMapping_Check(env)) {
5042 PyErr_SetString(PyExc_TypeError,
5043 "spawnve() arg 3 must be a mapping object");
5044 goto fail_0;
5045 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005046
Victor Stinner8c62be82010-05-06 00:08:46 +00005047 argvlist = PyMem_NEW(char *, argc+1);
5048 if (argvlist == NULL) {
5049 PyErr_NoMemory();
5050 goto fail_0;
5051 }
5052 for (i = 0; i < argc; i++) {
5053 if (!fsconvert_strdup((*getitem)(argv, i),
5054 &argvlist[i]))
5055 {
5056 lastarg = i;
5057 goto fail_1;
5058 }
5059 }
5060 lastarg = argc;
5061 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005062
Victor Stinner8c62be82010-05-06 00:08:46 +00005063 envlist = parse_envlist(env, &envc);
5064 if (envlist == NULL)
5065 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005066
Victor Stinner8c62be82010-05-06 00:08:46 +00005067 if (mode == _OLD_P_OVERLAY)
5068 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005069
Victor Stinner8c62be82010-05-06 00:08:46 +00005070 Py_BEGIN_ALLOW_THREADS
5071 spawnval = _spawnve(mode, path, argvlist, envlist);
5072 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005073
Victor Stinner8c62be82010-05-06 00:08:46 +00005074 if (spawnval == -1)
5075 (void) posix_error();
5076 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005077#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005078 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005079#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005080 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005081#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005082
Victor Stinner8c62be82010-05-06 00:08:46 +00005083 while (--envc >= 0)
5084 PyMem_DEL(envlist[envc]);
5085 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005086 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005087 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005088 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005089 Py_DECREF(opath);
5090 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005091}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005092
Guido van Rossuma1065681999-01-25 23:20:23 +00005093#endif /* HAVE_SPAWNV */
5094
5095
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005096#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005097PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005098"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005099Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5100\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005101Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005102
5103static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005104posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005105{
Victor Stinner8c62be82010-05-06 00:08:46 +00005106 pid_t pid;
5107 int result = 0;
5108 _PyImport_AcquireLock();
5109 pid = fork1();
5110 if (pid == 0) {
5111 /* child: this clobbers and resets the import lock. */
5112 PyOS_AfterFork();
5113 } else {
5114 /* parent: release the import lock. */
5115 result = _PyImport_ReleaseLock();
5116 }
5117 if (pid == -1)
5118 return posix_error();
5119 if (result < 0) {
5120 /* Don't clobber the OSError if the fork failed. */
5121 PyErr_SetString(PyExc_RuntimeError,
5122 "not holding the import lock");
5123 return NULL;
5124 }
5125 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005126}
5127#endif
5128
5129
Guido van Rossumad0ee831995-03-01 10:34:45 +00005130#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005131PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005132"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005133Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005134Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005135
Barry Warsaw53699e91996-12-10 23:23:01 +00005136static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005137posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005138{
Victor Stinner8c62be82010-05-06 00:08:46 +00005139 pid_t pid;
5140 int result = 0;
5141 _PyImport_AcquireLock();
5142 pid = fork();
5143 if (pid == 0) {
5144 /* child: this clobbers and resets the import lock. */
5145 PyOS_AfterFork();
5146 } else {
5147 /* parent: release the import lock. */
5148 result = _PyImport_ReleaseLock();
5149 }
5150 if (pid == -1)
5151 return posix_error();
5152 if (result < 0) {
5153 /* Don't clobber the OSError if the fork failed. */
5154 PyErr_SetString(PyExc_RuntimeError,
5155 "not holding the import lock");
5156 return NULL;
5157 }
5158 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005159}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005160#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005161
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005162#ifdef HAVE_SCHED_H
5163
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005164#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5165
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005166PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5167"sched_get_priority_max(policy)\n\n\
5168Get the maximum scheduling priority for *policy*.");
5169
5170static PyObject *
5171posix_sched_get_priority_max(PyObject *self, PyObject *args)
5172{
5173 int policy, max;
5174
5175 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5176 return NULL;
5177 max = sched_get_priority_max(policy);
5178 if (max < 0)
5179 return posix_error();
5180 return PyLong_FromLong(max);
5181}
5182
5183PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5184"sched_get_priority_min(policy)\n\n\
5185Get the minimum scheduling priority for *policy*.");
5186
5187static PyObject *
5188posix_sched_get_priority_min(PyObject *self, PyObject *args)
5189{
5190 int policy, min;
5191
5192 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5193 return NULL;
5194 min = sched_get_priority_min(policy);
5195 if (min < 0)
5196 return posix_error();
5197 return PyLong_FromLong(min);
5198}
5199
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005200#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5201
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005202#ifdef HAVE_SCHED_SETSCHEDULER
5203
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005204PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5205"sched_getscheduler(pid)\n\n\
5206Get the scheduling policy for the process with a PID of *pid*.\n\
5207Passing a PID of 0 returns the scheduling policy for the calling process.");
5208
5209static PyObject *
5210posix_sched_getscheduler(PyObject *self, PyObject *args)
5211{
5212 pid_t pid;
5213 int policy;
5214
5215 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5216 return NULL;
5217 policy = sched_getscheduler(pid);
5218 if (policy < 0)
5219 return posix_error();
5220 return PyLong_FromLong(policy);
5221}
5222
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005223#endif
5224
5225#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5226
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005227static PyObject *
5228sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5229{
5230 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005231 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005232
5233 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5234 return NULL;
5235 res = PyStructSequence_New(type);
5236 if (!res)
5237 return NULL;
5238 Py_INCREF(priority);
5239 PyStructSequence_SET_ITEM(res, 0, priority);
5240 return res;
5241}
5242
5243PyDoc_STRVAR(sched_param__doc__,
5244"sched_param(sched_priority): A scheduling parameter.\n\n\
5245Current has only one field: sched_priority");
5246
5247static PyStructSequence_Field sched_param_fields[] = {
5248 {"sched_priority", "the scheduling priority"},
5249 {0}
5250};
5251
5252static PyStructSequence_Desc sched_param_desc = {
5253 "sched_param", /* name */
5254 sched_param__doc__, /* doc */
5255 sched_param_fields,
5256 1
5257};
5258
5259static int
5260convert_sched_param(PyObject *param, struct sched_param *res)
5261{
5262 long priority;
5263
5264 if (Py_TYPE(param) != &SchedParamType) {
5265 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5266 return 0;
5267 }
5268 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5269 if (priority == -1 && PyErr_Occurred())
5270 return 0;
5271 if (priority > INT_MAX || priority < INT_MIN) {
5272 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5273 return 0;
5274 }
5275 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5276 return 1;
5277}
5278
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005279#endif
5280
5281#ifdef HAVE_SCHED_SETSCHEDULER
5282
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005283PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5284"sched_setscheduler(pid, policy, param)\n\n\
5285Set the scheduling policy, *policy*, for *pid*.\n\
5286If *pid* is 0, the calling process is changed.\n\
5287*param* is an instance of sched_param.");
5288
5289static PyObject *
5290posix_sched_setscheduler(PyObject *self, PyObject *args)
5291{
5292 pid_t pid;
5293 int policy;
5294 struct sched_param param;
5295
5296 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5297 &pid, &policy, &convert_sched_param, &param))
5298 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005299
5300 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005301 ** sched_setscheduler() returns 0 in Linux, but the previous
5302 ** scheduling policy under Solaris/Illumos, and others.
5303 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005304 */
5305 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005306 return posix_error();
5307 Py_RETURN_NONE;
5308}
5309
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005310#endif
5311
5312#ifdef HAVE_SCHED_SETPARAM
5313
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005314PyDoc_STRVAR(posix_sched_getparam__doc__,
5315"sched_getparam(pid) -> sched_param\n\n\
5316Returns scheduling parameters for the process with *pid* as an instance of the\n\
5317sched_param class. A PID of 0 means the calling process.");
5318
5319static PyObject *
5320posix_sched_getparam(PyObject *self, PyObject *args)
5321{
5322 pid_t pid;
5323 struct sched_param param;
5324 PyObject *res, *priority;
5325
5326 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5327 return NULL;
5328 if (sched_getparam(pid, &param))
5329 return posix_error();
5330 res = PyStructSequence_New(&SchedParamType);
5331 if (!res)
5332 return NULL;
5333 priority = PyLong_FromLong(param.sched_priority);
5334 if (!priority) {
5335 Py_DECREF(res);
5336 return NULL;
5337 }
5338 PyStructSequence_SET_ITEM(res, 0, priority);
5339 return res;
5340}
5341
5342PyDoc_STRVAR(posix_sched_setparam__doc__,
5343"sched_setparam(pid, param)\n\n\
5344Set scheduling parameters for a process with PID *pid*.\n\
5345A PID of 0 means the calling process.");
5346
5347static PyObject *
5348posix_sched_setparam(PyObject *self, PyObject *args)
5349{
5350 pid_t pid;
5351 struct sched_param param;
5352
5353 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5354 &pid, &convert_sched_param, &param))
5355 return NULL;
5356 if (sched_setparam(pid, &param))
5357 return posix_error();
5358 Py_RETURN_NONE;
5359}
5360
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005361#endif
5362
5363#ifdef HAVE_SCHED_RR_GET_INTERVAL
5364
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005365PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5366"sched_rr_get_interval(pid) -> float\n\n\
5367Return the round-robin quantum for the process with PID *pid* in seconds.");
5368
5369static PyObject *
5370posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5371{
5372 pid_t pid;
5373 struct timespec interval;
5374
5375 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5376 return NULL;
5377 if (sched_rr_get_interval(pid, &interval))
5378 return posix_error();
5379 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5380}
5381
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005382#endif
5383
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005384PyDoc_STRVAR(posix_sched_yield__doc__,
5385"sched_yield()\n\n\
5386Voluntarily relinquish the CPU.");
5387
5388static PyObject *
5389posix_sched_yield(PyObject *self, PyObject *noargs)
5390{
5391 if (sched_yield())
5392 return posix_error();
5393 Py_RETURN_NONE;
5394}
5395
Benjamin Peterson2740af82011-08-02 17:41:34 -05005396#ifdef HAVE_SCHED_SETAFFINITY
5397
Antoine Pitrou84869872012-08-04 16:16:35 +02005398/* The minimum number of CPUs allocated in a cpu_set_t */
5399static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005400
5401PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5402"sched_setaffinity(pid, cpu_set)\n\n\
5403Set the affinity of the process with PID *pid* to *cpu_set*.");
5404
5405static PyObject *
5406posix_sched_setaffinity(PyObject *self, PyObject *args)
5407{
5408 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005409 int ncpus;
5410 size_t setsize;
5411 cpu_set_t *mask = NULL;
5412 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005413
Antoine Pitrou84869872012-08-04 16:16:35 +02005414 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5415 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005416 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005417
5418 iterator = PyObject_GetIter(iterable);
5419 if (iterator == NULL)
5420 return NULL;
5421
5422 ncpus = NCPUS_START;
5423 setsize = CPU_ALLOC_SIZE(ncpus);
5424 mask = CPU_ALLOC(ncpus);
5425 if (mask == NULL) {
5426 PyErr_NoMemory();
5427 goto error;
5428 }
5429 CPU_ZERO_S(setsize, mask);
5430
5431 while ((item = PyIter_Next(iterator))) {
5432 long cpu;
5433 if (!PyLong_Check(item)) {
5434 PyErr_Format(PyExc_TypeError,
5435 "expected an iterator of ints, "
5436 "but iterator yielded %R",
5437 Py_TYPE(item));
5438 Py_DECREF(item);
5439 goto error;
5440 }
5441 cpu = PyLong_AsLong(item);
5442 Py_DECREF(item);
5443 if (cpu < 0) {
5444 if (!PyErr_Occurred())
5445 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5446 goto error;
5447 }
5448 if (cpu > INT_MAX - 1) {
5449 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5450 goto error;
5451 }
5452 if (cpu >= ncpus) {
5453 /* Grow CPU mask to fit the CPU number */
5454 int newncpus = ncpus;
5455 cpu_set_t *newmask;
5456 size_t newsetsize;
5457 while (newncpus <= cpu) {
5458 if (newncpus > INT_MAX / 2)
5459 newncpus = cpu + 1;
5460 else
5461 newncpus = newncpus * 2;
5462 }
5463 newmask = CPU_ALLOC(newncpus);
5464 if (newmask == NULL) {
5465 PyErr_NoMemory();
5466 goto error;
5467 }
5468 newsetsize = CPU_ALLOC_SIZE(newncpus);
5469 CPU_ZERO_S(newsetsize, newmask);
5470 memcpy(newmask, mask, setsize);
5471 CPU_FREE(mask);
5472 setsize = newsetsize;
5473 mask = newmask;
5474 ncpus = newncpus;
5475 }
5476 CPU_SET_S(cpu, setsize, mask);
5477 }
5478 Py_CLEAR(iterator);
5479
5480 if (sched_setaffinity(pid, setsize, mask)) {
5481 posix_error();
5482 goto error;
5483 }
5484 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005485 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005486
5487error:
5488 if (mask)
5489 CPU_FREE(mask);
5490 Py_XDECREF(iterator);
5491 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005492}
5493
5494PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5495"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5496Return the affinity of the process with PID *pid*.\n\
5497The returned cpu_set will be of size *ncpus*.");
5498
5499static PyObject *
5500posix_sched_getaffinity(PyObject *self, PyObject *args)
5501{
5502 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005503 int cpu, ncpus, count;
5504 size_t setsize;
5505 cpu_set_t *mask = NULL;
5506 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005507
Antoine Pitrou84869872012-08-04 16:16:35 +02005508 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
5509 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005510 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005511
5512 ncpus = NCPUS_START;
5513 while (1) {
5514 setsize = CPU_ALLOC_SIZE(ncpus);
5515 mask = CPU_ALLOC(ncpus);
5516 if (mask == NULL)
5517 return PyErr_NoMemory();
5518 if (sched_getaffinity(pid, setsize, mask) == 0)
5519 break;
5520 CPU_FREE(mask);
5521 if (errno != EINVAL)
5522 return posix_error();
5523 if (ncpus > INT_MAX / 2) {
5524 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5525 "a large enough CPU set");
5526 return NULL;
5527 }
5528 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005529 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005530
5531 res = PySet_New(NULL);
5532 if (res == NULL)
5533 goto error;
5534 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5535 if (CPU_ISSET_S(cpu, setsize, mask)) {
5536 PyObject *cpu_num = PyLong_FromLong(cpu);
5537 --count;
5538 if (cpu_num == NULL)
5539 goto error;
5540 if (PySet_Add(res, cpu_num)) {
5541 Py_DECREF(cpu_num);
5542 goto error;
5543 }
5544 Py_DECREF(cpu_num);
5545 }
5546 }
5547 CPU_FREE(mask);
5548 return res;
5549
5550error:
5551 if (mask)
5552 CPU_FREE(mask);
5553 Py_XDECREF(res);
5554 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005555}
5556
Benjamin Peterson2740af82011-08-02 17:41:34 -05005557#endif /* HAVE_SCHED_SETAFFINITY */
5558
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005559#endif /* HAVE_SCHED_H */
5560
Neal Norwitzb59798b2003-03-21 01:43:31 +00005561/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005562/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5563#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005564#define DEV_PTY_FILE "/dev/ptc"
5565#define HAVE_DEV_PTMX
5566#else
5567#define DEV_PTY_FILE "/dev/ptmx"
5568#endif
5569
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005570#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005571#ifdef HAVE_PTY_H
5572#include <pty.h>
5573#else
5574#ifdef HAVE_LIBUTIL_H
5575#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005576#else
5577#ifdef HAVE_UTIL_H
5578#include <util.h>
5579#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005580#endif /* HAVE_LIBUTIL_H */
5581#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005582#ifdef HAVE_STROPTS_H
5583#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005584#endif
5585#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005586
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005587#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005588PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005589"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005590Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005591
5592static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005593posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005594{
Victor Stinner8c62be82010-05-06 00:08:46 +00005595 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005596#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005597 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005598#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005599#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005600 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005601#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005602 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005603#endif
5604#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005605
Thomas Wouters70c21a12000-07-14 14:28:33 +00005606#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005607 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
5608 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005609#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005610 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5611 if (slave_name == NULL)
5612 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00005613
Victor Stinner8c62be82010-05-06 00:08:46 +00005614 slave_fd = open(slave_name, O_RDWR);
5615 if (slave_fd < 0)
5616 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005617#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005618 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
5619 if (master_fd < 0)
5620 return posix_error();
5621 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
5622 /* change permission of slave */
5623 if (grantpt(master_fd) < 0) {
5624 PyOS_setsig(SIGCHLD, sig_saved);
5625 return posix_error();
5626 }
5627 /* unlock slave */
5628 if (unlockpt(master_fd) < 0) {
5629 PyOS_setsig(SIGCHLD, sig_saved);
5630 return posix_error();
5631 }
5632 PyOS_setsig(SIGCHLD, sig_saved);
5633 slave_name = ptsname(master_fd); /* get name of slave */
5634 if (slave_name == NULL)
5635 return posix_error();
5636 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
5637 if (slave_fd < 0)
5638 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005639#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005640 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5641 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005642#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005643 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005644#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005645#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005646#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005647
Victor Stinner8c62be82010-05-06 00:08:46 +00005648 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005649
Fred Drake8cef4cf2000-06-28 16:40:38 +00005650}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005651#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005652
5653#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005654PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005655"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00005656Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
5657Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005658To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005659
5660static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005661posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005662{
Victor Stinner8c62be82010-05-06 00:08:46 +00005663 int master_fd = -1, result = 0;
5664 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005665
Victor Stinner8c62be82010-05-06 00:08:46 +00005666 _PyImport_AcquireLock();
5667 pid = forkpty(&master_fd, NULL, NULL, NULL);
5668 if (pid == 0) {
5669 /* child: this clobbers and resets the import lock. */
5670 PyOS_AfterFork();
5671 } else {
5672 /* parent: release the import lock. */
5673 result = _PyImport_ReleaseLock();
5674 }
5675 if (pid == -1)
5676 return posix_error();
5677 if (result < 0) {
5678 /* Don't clobber the OSError if the fork failed. */
5679 PyErr_SetString(PyExc_RuntimeError,
5680 "not holding the import lock");
5681 return NULL;
5682 }
5683 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005684}
5685#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005686
Ross Lagerwall7807c352011-03-17 20:20:30 +02005687
Guido van Rossumad0ee831995-03-01 10:34:45 +00005688#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005689PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005690"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005691Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005692
Barry Warsaw53699e91996-12-10 23:23:01 +00005693static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005694posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005695{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005696 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005697}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005698#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005699
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005700
Guido van Rossumad0ee831995-03-01 10:34:45 +00005701#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005702PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005703"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005704Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005705
Barry Warsaw53699e91996-12-10 23:23:01 +00005706static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005707posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005708{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005709 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005710}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005711#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005712
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005713
Guido van Rossumad0ee831995-03-01 10:34:45 +00005714#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005715PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005716"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005717Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005718
Barry Warsaw53699e91996-12-10 23:23:01 +00005719static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005720posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005721{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005722 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005723}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005724#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005725
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005726
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005727PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005728"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005729Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005730
Barry Warsaw53699e91996-12-10 23:23:01 +00005731static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005732posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005733{
Victor Stinner8c62be82010-05-06 00:08:46 +00005734 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005735}
5736
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005737#ifdef HAVE_GETGROUPLIST
5738PyDoc_STRVAR(posix_getgrouplist__doc__,
5739"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5740Returns a list of groups to which a user belongs.\n\n\
5741 user: username to lookup\n\
5742 group: base group id of the user");
5743
5744static PyObject *
5745posix_getgrouplist(PyObject *self, PyObject *args)
5746{
5747#ifdef NGROUPS_MAX
5748#define MAX_GROUPS NGROUPS_MAX
5749#else
5750 /* defined to be 16 on Solaris7, so this should be a small number */
5751#define MAX_GROUPS 64
5752#endif
5753
5754 const char *user;
5755 int i, ngroups;
5756 PyObject *list;
5757#ifdef __APPLE__
5758 int *groups, basegid;
5759#else
5760 gid_t *groups, basegid;
5761#endif
5762 ngroups = MAX_GROUPS;
5763
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005764#ifdef __APPLE__
5765 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005766 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005767#else
5768 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
5769 _Py_Gid_Converter, &basegid))
5770 return NULL;
5771#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005772
5773#ifdef __APPLE__
5774 groups = PyMem_Malloc(ngroups * sizeof(int));
5775#else
5776 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
5777#endif
5778 if (groups == NULL)
5779 return PyErr_NoMemory();
5780
5781 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
5782 PyMem_Del(groups);
5783 return posix_error();
5784 }
5785
5786 list = PyList_New(ngroups);
5787 if (list == NULL) {
5788 PyMem_Del(groups);
5789 return NULL;
5790 }
5791
5792 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005793#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005794 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005795#else
5796 PyObject *o = _PyLong_FromGid(groups[i]);
5797#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005798 if (o == NULL) {
5799 Py_DECREF(list);
5800 PyMem_Del(groups);
5801 return NULL;
5802 }
5803 PyList_SET_ITEM(list, i, o);
5804 }
5805
5806 PyMem_Del(groups);
5807
5808 return list;
5809}
5810#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005811
Fred Drakec9680921999-12-13 16:37:25 +00005812#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005813PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005814"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005815Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00005816
5817static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005818posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00005819{
5820 PyObject *result = NULL;
5821
Fred Drakec9680921999-12-13 16:37:25 +00005822#ifdef NGROUPS_MAX
5823#define MAX_GROUPS NGROUPS_MAX
5824#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005825 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00005826#define MAX_GROUPS 64
5827#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005828 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005829
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005830 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005831 * This is a helper variable to store the intermediate result when
5832 * that happens.
5833 *
5834 * To keep the code readable the OSX behaviour is unconditional,
5835 * according to the POSIX spec this should be safe on all unix-y
5836 * systems.
5837 */
5838 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005839 int n;
Fred Drakec9680921999-12-13 16:37:25 +00005840
Victor Stinner8c62be82010-05-06 00:08:46 +00005841 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005842 if (n < 0) {
5843 if (errno == EINVAL) {
5844 n = getgroups(0, NULL);
5845 if (n == -1) {
5846 return posix_error();
5847 }
5848 if (n == 0) {
5849 /* Avoid malloc(0) */
5850 alt_grouplist = grouplist;
5851 } else {
5852 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
5853 if (alt_grouplist == NULL) {
5854 errno = EINVAL;
5855 return posix_error();
5856 }
5857 n = getgroups(n, alt_grouplist);
5858 if (n == -1) {
5859 PyMem_Free(alt_grouplist);
5860 return posix_error();
5861 }
5862 }
5863 } else {
5864 return posix_error();
5865 }
5866 }
5867 result = PyList_New(n);
5868 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005869 int i;
5870 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005871 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00005872 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00005873 Py_DECREF(result);
5874 result = NULL;
5875 break;
Fred Drakec9680921999-12-13 16:37:25 +00005876 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005877 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00005878 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005879 }
5880
5881 if (alt_grouplist != grouplist) {
5882 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005883 }
Neal Norwitze241ce82003-02-17 18:17:05 +00005884
Fred Drakec9680921999-12-13 16:37:25 +00005885 return result;
5886}
5887#endif
5888
Antoine Pitroub7572f02009-12-02 20:46:48 +00005889#ifdef HAVE_INITGROUPS
5890PyDoc_STRVAR(posix_initgroups__doc__,
5891"initgroups(username, gid) -> None\n\n\
5892Call the system initgroups() to initialize the group access list with all of\n\
5893the groups of which the specified username is a member, plus the specified\n\
5894group id.");
5895
5896static PyObject *
5897posix_initgroups(PyObject *self, PyObject *args)
5898{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005899 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00005900 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005901 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005902#ifdef __APPLE__
5903 int gid;
5904#else
5905 gid_t gid;
5906#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00005907
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005908#ifdef __APPLE__
5909 if (!PyArg_ParseTuple(args, "O&i:initgroups",
5910 PyUnicode_FSConverter, &oname,
5911 &gid))
5912#else
5913 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
5914 PyUnicode_FSConverter, &oname,
5915 _Py_Gid_Converter, &gid))
5916#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005917 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005918 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005919
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005920 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005921 Py_DECREF(oname);
5922 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00005923 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005924
Victor Stinner8c62be82010-05-06 00:08:46 +00005925 Py_INCREF(Py_None);
5926 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005927}
5928#endif
5929
Martin v. Löwis606edc12002-06-13 21:09:11 +00005930#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005931PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005932"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005933Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00005934
5935static PyObject *
5936posix_getpgid(PyObject *self, PyObject *args)
5937{
Victor Stinner8c62be82010-05-06 00:08:46 +00005938 pid_t pid, pgid;
5939 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
5940 return NULL;
5941 pgid = getpgid(pid);
5942 if (pgid < 0)
5943 return posix_error();
5944 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00005945}
5946#endif /* HAVE_GETPGID */
5947
5948
Guido van Rossumb6775db1994-08-01 11:34:53 +00005949#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005950PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005951"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005952Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005953
Barry Warsaw53699e91996-12-10 23:23:01 +00005954static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005955posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00005956{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005957#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005958 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005959#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005960 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005961#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00005962}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005963#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00005964
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005965
Guido van Rossumb6775db1994-08-01 11:34:53 +00005966#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005967PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005968"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00005969Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005970
Barry Warsaw53699e91996-12-10 23:23:01 +00005971static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005972posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005973{
Guido van Rossum64933891994-10-20 21:56:42 +00005974#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005975 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005976#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005977 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005978#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005979 return posix_error();
5980 Py_INCREF(Py_None);
5981 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005982}
5983
Guido van Rossumb6775db1994-08-01 11:34:53 +00005984#endif /* HAVE_SETPGRP */
5985
Guido van Rossumad0ee831995-03-01 10:34:45 +00005986#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005987
5988#ifdef MS_WINDOWS
5989#include <tlhelp32.h>
5990
5991static PyObject*
5992win32_getppid()
5993{
5994 HANDLE snapshot;
5995 pid_t mypid;
5996 PyObject* result = NULL;
5997 BOOL have_record;
5998 PROCESSENTRY32 pe;
5999
6000 mypid = getpid(); /* This function never fails */
6001
6002 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6003 if (snapshot == INVALID_HANDLE_VALUE)
6004 return PyErr_SetFromWindowsErr(GetLastError());
6005
6006 pe.dwSize = sizeof(pe);
6007 have_record = Process32First(snapshot, &pe);
6008 while (have_record) {
6009 if (mypid == (pid_t)pe.th32ProcessID) {
6010 /* We could cache the ulong value in a static variable. */
6011 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6012 break;
6013 }
6014
6015 have_record = Process32Next(snapshot, &pe);
6016 }
6017
6018 /* If our loop exits and our pid was not found (result will be NULL)
6019 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6020 * error anyway, so let's raise it. */
6021 if (!result)
6022 result = PyErr_SetFromWindowsErr(GetLastError());
6023
6024 CloseHandle(snapshot);
6025
6026 return result;
6027}
6028#endif /*MS_WINDOWS*/
6029
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006030PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006031"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006032Return the parent's process id. If the parent process has already exited,\n\
6033Windows machines will still return its id; others systems will return the id\n\
6034of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006035
Barry Warsaw53699e91996-12-10 23:23:01 +00006036static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006037posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006038{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006039#ifdef MS_WINDOWS
6040 return win32_getppid();
6041#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006042 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006043#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006044}
6045#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006046
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006047
Fred Drake12c6e2d1999-12-14 21:25:03 +00006048#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006049PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006050"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006051Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006052
6053static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006054posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006055{
Victor Stinner8c62be82010-05-06 00:08:46 +00006056 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006057#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006058 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006059 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006060
6061 if (GetUserNameW(user_name, &num_chars)) {
6062 /* num_chars is the number of unicode chars plus null terminator */
6063 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006064 }
6065 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006066 result = PyErr_SetFromWindowsErr(GetLastError());
6067#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006068 char *name;
6069 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006070
Victor Stinner8c62be82010-05-06 00:08:46 +00006071 errno = 0;
6072 name = getlogin();
6073 if (name == NULL) {
6074 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006075 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006076 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006077 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006078 }
6079 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006080 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006081 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006082#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006083 return result;
6084}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006085#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006086
Guido van Rossumad0ee831995-03-01 10:34:45 +00006087#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006088PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006089"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006090Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006091
Barry Warsaw53699e91996-12-10 23:23:01 +00006092static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006093posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006094{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006095 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006096}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006097#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006098
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006099
Guido van Rossumad0ee831995-03-01 10:34:45 +00006100#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006101PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006102"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006103Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006104
Barry Warsaw53699e91996-12-10 23:23:01 +00006105static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006106posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006107{
Victor Stinner8c62be82010-05-06 00:08:46 +00006108 pid_t pid;
6109 int sig;
6110 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6111 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006112 if (kill(pid, sig) == -1)
6113 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006114 Py_INCREF(Py_None);
6115 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006116}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006117#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006118
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006119#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006120PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006121"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006122Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006123
6124static PyObject *
6125posix_killpg(PyObject *self, PyObject *args)
6126{
Victor Stinner8c62be82010-05-06 00:08:46 +00006127 int sig;
6128 pid_t pgid;
6129 /* XXX some man pages make the `pgid` parameter an int, others
6130 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6131 take the same type. Moreover, pid_t is always at least as wide as
6132 int (else compilation of this module fails), which is safe. */
6133 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6134 return NULL;
6135 if (killpg(pgid, sig) == -1)
6136 return posix_error();
6137 Py_INCREF(Py_None);
6138 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006139}
6140#endif
6141
Brian Curtineb24d742010-04-12 17:16:38 +00006142#ifdef MS_WINDOWS
6143PyDoc_STRVAR(win32_kill__doc__,
6144"kill(pid, sig)\n\n\
6145Kill a process with a signal.");
6146
6147static PyObject *
6148win32_kill(PyObject *self, PyObject *args)
6149{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006150 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00006151 DWORD pid, sig, err;
6152 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006153
Victor Stinner8c62be82010-05-06 00:08:46 +00006154 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
6155 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006156
Victor Stinner8c62be82010-05-06 00:08:46 +00006157 /* Console processes which share a common console can be sent CTRL+C or
6158 CTRL+BREAK events, provided they handle said events. */
6159 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
6160 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
6161 err = GetLastError();
6162 PyErr_SetFromWindowsErr(err);
6163 }
6164 else
6165 Py_RETURN_NONE;
6166 }
Brian Curtineb24d742010-04-12 17:16:38 +00006167
Victor Stinner8c62be82010-05-06 00:08:46 +00006168 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6169 attempt to open and terminate the process. */
6170 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
6171 if (handle == NULL) {
6172 err = GetLastError();
6173 return PyErr_SetFromWindowsErr(err);
6174 }
Brian Curtineb24d742010-04-12 17:16:38 +00006175
Victor Stinner8c62be82010-05-06 00:08:46 +00006176 if (TerminateProcess(handle, sig) == 0) {
6177 err = GetLastError();
6178 result = PyErr_SetFromWindowsErr(err);
6179 } else {
6180 Py_INCREF(Py_None);
6181 result = Py_None;
6182 }
Brian Curtineb24d742010-04-12 17:16:38 +00006183
Victor Stinner8c62be82010-05-06 00:08:46 +00006184 CloseHandle(handle);
6185 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006186}
6187#endif /* MS_WINDOWS */
6188
Guido van Rossumc0125471996-06-28 18:55:32 +00006189#ifdef HAVE_PLOCK
6190
6191#ifdef HAVE_SYS_LOCK_H
6192#include <sys/lock.h>
6193#endif
6194
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006195PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006196"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006197Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006198
Barry Warsaw53699e91996-12-10 23:23:01 +00006199static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006200posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006201{
Victor Stinner8c62be82010-05-06 00:08:46 +00006202 int op;
6203 if (!PyArg_ParseTuple(args, "i:plock", &op))
6204 return NULL;
6205 if (plock(op) == -1)
6206 return posix_error();
6207 Py_INCREF(Py_None);
6208 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006209}
6210#endif
6211
Guido van Rossumb6775db1994-08-01 11:34:53 +00006212#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006213PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006214"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006215Set the current process's user id.");
6216
Barry Warsaw53699e91996-12-10 23:23:01 +00006217static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006218posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006219{
Victor Stinner8c62be82010-05-06 00:08:46 +00006220 uid_t uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006221 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006222 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006223 if (setuid(uid) < 0)
6224 return posix_error();
6225 Py_INCREF(Py_None);
6226 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006227}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006228#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006229
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006230
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006231#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006232PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006233"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006234Set the current process's effective user id.");
6235
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006236static PyObject *
6237posix_seteuid (PyObject *self, PyObject *args)
6238{
Victor Stinner8c62be82010-05-06 00:08:46 +00006239 uid_t euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006240 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006241 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006242 if (seteuid(euid) < 0) {
6243 return posix_error();
6244 } else {
6245 Py_INCREF(Py_None);
6246 return Py_None;
6247 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006248}
6249#endif /* HAVE_SETEUID */
6250
6251#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006252PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006253"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006254Set the current process's effective group id.");
6255
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006256static PyObject *
6257posix_setegid (PyObject *self, PyObject *args)
6258{
Victor Stinner8c62be82010-05-06 00:08:46 +00006259 gid_t egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006260 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006261 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006262 if (setegid(egid) < 0) {
6263 return posix_error();
6264 } else {
6265 Py_INCREF(Py_None);
6266 return Py_None;
6267 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006268}
6269#endif /* HAVE_SETEGID */
6270
6271#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006272PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006273"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006274Set the current process's real and effective user ids.");
6275
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006276static PyObject *
6277posix_setreuid (PyObject *self, PyObject *args)
6278{
Victor Stinner8c62be82010-05-06 00:08:46 +00006279 uid_t ruid, euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006280 if (!PyArg_ParseTuple(args, "O&O&:setreuid",
6281 _Py_Uid_Converter, &ruid,
6282 _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006283 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006284 if (setreuid(ruid, euid) < 0) {
6285 return posix_error();
6286 } else {
6287 Py_INCREF(Py_None);
6288 return Py_None;
6289 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006290}
6291#endif /* HAVE_SETREUID */
6292
6293#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006294PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006295"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006296Set the current process's real and effective group ids.");
6297
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006298static PyObject *
6299posix_setregid (PyObject *self, PyObject *args)
6300{
Victor Stinner8c62be82010-05-06 00:08:46 +00006301 gid_t rgid, egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006302 if (!PyArg_ParseTuple(args, "O&O&:setregid",
6303 _Py_Gid_Converter, &rgid,
6304 _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006305 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006306 if (setregid(rgid, egid) < 0) {
6307 return posix_error();
6308 } else {
6309 Py_INCREF(Py_None);
6310 return Py_None;
6311 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006312}
6313#endif /* HAVE_SETREGID */
6314
Guido van Rossumb6775db1994-08-01 11:34:53 +00006315#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006316PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006317"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006318Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006319
Barry Warsaw53699e91996-12-10 23:23:01 +00006320static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006321posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006322{
Victor Stinner8c62be82010-05-06 00:08:46 +00006323 gid_t gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006324 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006325 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006326 if (setgid(gid) < 0)
6327 return posix_error();
6328 Py_INCREF(Py_None);
6329 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006330}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006331#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006332
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006333#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006334PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006335"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006336Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006337
6338static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006339posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006340{
Victor Stinner8c62be82010-05-06 00:08:46 +00006341 int i, len;
6342 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006343
Victor Stinner8c62be82010-05-06 00:08:46 +00006344 if (!PySequence_Check(groups)) {
6345 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6346 return NULL;
6347 }
6348 len = PySequence_Size(groups);
6349 if (len > MAX_GROUPS) {
6350 PyErr_SetString(PyExc_ValueError, "too many groups");
6351 return NULL;
6352 }
6353 for(i = 0; i < len; i++) {
6354 PyObject *elem;
6355 elem = PySequence_GetItem(groups, i);
6356 if (!elem)
6357 return NULL;
6358 if (!PyLong_Check(elem)) {
6359 PyErr_SetString(PyExc_TypeError,
6360 "groups must be integers");
6361 Py_DECREF(elem);
6362 return NULL;
6363 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006364 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006365 Py_DECREF(elem);
6366 return NULL;
6367 }
6368 }
6369 Py_DECREF(elem);
6370 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006371
Victor Stinner8c62be82010-05-06 00:08:46 +00006372 if (setgroups(len, grouplist) < 0)
6373 return posix_error();
6374 Py_INCREF(Py_None);
6375 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006376}
6377#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006378
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006379#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6380static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006381wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006382{
Victor Stinner8c62be82010-05-06 00:08:46 +00006383 PyObject *result;
6384 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006385 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006386
Victor Stinner8c62be82010-05-06 00:08:46 +00006387 if (pid == -1)
6388 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006389
Victor Stinner8c62be82010-05-06 00:08:46 +00006390 if (struct_rusage == NULL) {
6391 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6392 if (m == NULL)
6393 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006394 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006395 Py_DECREF(m);
6396 if (struct_rusage == NULL)
6397 return NULL;
6398 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006399
Victor Stinner8c62be82010-05-06 00:08:46 +00006400 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6401 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6402 if (!result)
6403 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006404
6405#ifndef doubletime
6406#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6407#endif
6408
Victor Stinner8c62be82010-05-06 00:08:46 +00006409 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006410 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006411 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006412 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006413#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006414 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6415 SET_INT(result, 2, ru->ru_maxrss);
6416 SET_INT(result, 3, ru->ru_ixrss);
6417 SET_INT(result, 4, ru->ru_idrss);
6418 SET_INT(result, 5, ru->ru_isrss);
6419 SET_INT(result, 6, ru->ru_minflt);
6420 SET_INT(result, 7, ru->ru_majflt);
6421 SET_INT(result, 8, ru->ru_nswap);
6422 SET_INT(result, 9, ru->ru_inblock);
6423 SET_INT(result, 10, ru->ru_oublock);
6424 SET_INT(result, 11, ru->ru_msgsnd);
6425 SET_INT(result, 12, ru->ru_msgrcv);
6426 SET_INT(result, 13, ru->ru_nsignals);
6427 SET_INT(result, 14, ru->ru_nvcsw);
6428 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006429#undef SET_INT
6430
Victor Stinner8c62be82010-05-06 00:08:46 +00006431 if (PyErr_Occurred()) {
6432 Py_DECREF(result);
6433 return NULL;
6434 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006435
Victor Stinner8c62be82010-05-06 00:08:46 +00006436 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006437}
6438#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6439
6440#ifdef HAVE_WAIT3
6441PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006442"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006443Wait for completion of a child process.");
6444
6445static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006446posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006447{
Victor Stinner8c62be82010-05-06 00:08:46 +00006448 pid_t pid;
6449 int options;
6450 struct rusage ru;
6451 WAIT_TYPE status;
6452 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006453
Victor Stinner4195b5c2012-02-08 23:03:19 +01006454 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006455 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006456
Victor Stinner8c62be82010-05-06 00:08:46 +00006457 Py_BEGIN_ALLOW_THREADS
6458 pid = wait3(&status, options, &ru);
6459 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006460
Victor Stinner4195b5c2012-02-08 23:03:19 +01006461 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006462}
6463#endif /* HAVE_WAIT3 */
6464
6465#ifdef HAVE_WAIT4
6466PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006467"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006468Wait for completion of a given child process.");
6469
6470static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006471posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006472{
Victor Stinner8c62be82010-05-06 00:08:46 +00006473 pid_t pid;
6474 int options;
6475 struct rusage ru;
6476 WAIT_TYPE status;
6477 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006478
Victor Stinner4195b5c2012-02-08 23:03:19 +01006479 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006480 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006481
Victor Stinner8c62be82010-05-06 00:08:46 +00006482 Py_BEGIN_ALLOW_THREADS
6483 pid = wait4(pid, &status, options, &ru);
6484 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006485
Victor Stinner4195b5c2012-02-08 23:03:19 +01006486 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006487}
6488#endif /* HAVE_WAIT4 */
6489
Ross Lagerwall7807c352011-03-17 20:20:30 +02006490#if defined(HAVE_WAITID) && !defined(__APPLE__)
6491PyDoc_STRVAR(posix_waitid__doc__,
6492"waitid(idtype, id, options) -> waitid_result\n\n\
6493Wait for the completion of one or more child processes.\n\n\
6494idtype can be P_PID, P_PGID or P_ALL.\n\
6495id specifies the pid to wait on.\n\
6496options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6497or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6498Returns either waitid_result or None if WNOHANG is specified and there are\n\
6499no children in a waitable state.");
6500
6501static PyObject *
6502posix_waitid(PyObject *self, PyObject *args)
6503{
6504 PyObject *result;
6505 idtype_t idtype;
6506 id_t id;
6507 int options, res;
6508 siginfo_t si;
6509 si.si_pid = 0;
6510 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6511 return NULL;
6512 Py_BEGIN_ALLOW_THREADS
6513 res = waitid(idtype, id, &si, options);
6514 Py_END_ALLOW_THREADS
6515 if (res == -1)
6516 return posix_error();
6517
6518 if (si.si_pid == 0)
6519 Py_RETURN_NONE;
6520
6521 result = PyStructSequence_New(&WaitidResultType);
6522 if (!result)
6523 return NULL;
6524
6525 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006526 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006527 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6528 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6529 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6530 if (PyErr_Occurred()) {
6531 Py_DECREF(result);
6532 return NULL;
6533 }
6534
6535 return result;
6536}
6537#endif
6538
Guido van Rossumb6775db1994-08-01 11:34:53 +00006539#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006540PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006541"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006542Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006543
Barry Warsaw53699e91996-12-10 23:23:01 +00006544static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006545posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006546{
Victor Stinner8c62be82010-05-06 00:08:46 +00006547 pid_t pid;
6548 int options;
6549 WAIT_TYPE status;
6550 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006551
Victor Stinner8c62be82010-05-06 00:08:46 +00006552 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6553 return NULL;
6554 Py_BEGIN_ALLOW_THREADS
6555 pid = waitpid(pid, &status, options);
6556 Py_END_ALLOW_THREADS
6557 if (pid == -1)
6558 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006559
Victor Stinner8c62be82010-05-06 00:08:46 +00006560 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006561}
6562
Tim Petersab034fa2002-02-01 11:27:43 +00006563#elif defined(HAVE_CWAIT)
6564
6565/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006566PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006567"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006568"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006569
6570static PyObject *
6571posix_waitpid(PyObject *self, PyObject *args)
6572{
Victor Stinner8c62be82010-05-06 00:08:46 +00006573 Py_intptr_t pid;
6574 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006575
Victor Stinner8c62be82010-05-06 00:08:46 +00006576 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6577 return NULL;
6578 Py_BEGIN_ALLOW_THREADS
6579 pid = _cwait(&status, pid, options);
6580 Py_END_ALLOW_THREADS
6581 if (pid == -1)
6582 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006583
Victor Stinner8c62be82010-05-06 00:08:46 +00006584 /* shift the status left a byte so this is more like the POSIX waitpid */
6585 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006586}
6587#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006588
Guido van Rossumad0ee831995-03-01 10:34:45 +00006589#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006590PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006591"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006592Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006593
Barry Warsaw53699e91996-12-10 23:23:01 +00006594static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006595posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006596{
Victor Stinner8c62be82010-05-06 00:08:46 +00006597 pid_t pid;
6598 WAIT_TYPE status;
6599 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006600
Victor Stinner8c62be82010-05-06 00:08:46 +00006601 Py_BEGIN_ALLOW_THREADS
6602 pid = wait(&status);
6603 Py_END_ALLOW_THREADS
6604 if (pid == -1)
6605 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006606
Victor Stinner8c62be82010-05-06 00:08:46 +00006607 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006608}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006609#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006610
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006611
Larry Hastings9cf065c2012-06-22 16:30:09 -07006612#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
6613PyDoc_STRVAR(readlink__doc__,
6614"readlink(path, *, dir_fd=None) -> path\n\n\
6615Return a string representing the path to which the symbolic link points.\n\
6616\n\
6617If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6618 and path should be relative; path will then be relative to that directory.\n\
6619dir_fd may not be implemented on your platform.\n\
6620 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006621#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006622
Guido van Rossumb6775db1994-08-01 11:34:53 +00006623#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006624
Barry Warsaw53699e91996-12-10 23:23:01 +00006625static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006626posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006627{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006628 path_t path;
6629 int dir_fd = DEFAULT_DIR_FD;
6630 char buffer[MAXPATHLEN];
6631 ssize_t length;
6632 PyObject *return_value = NULL;
6633 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00006634
Larry Hastings9cf065c2012-06-22 16:30:09 -07006635 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01006636 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07006637 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
6638 path_converter, &path,
6639#ifdef HAVE_READLINKAT
6640 dir_fd_converter, &dir_fd
6641#else
6642 dir_fd_unavailable, &dir_fd
6643#endif
6644 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00006645 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00006646
Victor Stinner8c62be82010-05-06 00:08:46 +00006647 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07006648#ifdef HAVE_READLINKAT
6649 if (dir_fd != DEFAULT_DIR_FD)
6650 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00006651 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07006652#endif
6653 length = readlink(path.narrow, buffer, sizeof(buffer));
6654 Py_END_ALLOW_THREADS
6655
6656 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01006657 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006658 goto exit;
6659 }
6660
6661 if (PyUnicode_Check(path.object))
6662 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
6663 else
6664 return_value = PyBytes_FromStringAndSize(buffer, length);
6665exit:
6666 path_cleanup(&path);
6667 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006668}
Larry Hastings9cf065c2012-06-22 16:30:09 -07006669
6670
Guido van Rossumb6775db1994-08-01 11:34:53 +00006671#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006672
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006673
Larry Hastings9cf065c2012-06-22 16:30:09 -07006674#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006675PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07006676"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
6677Create a symbolic link pointing to src named dst.\n\n\
6678target_is_directory is required on Windows if the target is to be\n\
6679 interpreted as a directory. (On Windows, symlink requires\n\
6680 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
6681 target_is_directory is ignored on non-Windows platforms.\n\
6682\n\
6683If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6684 and path should be relative; path will then be relative to that directory.\n\
6685dir_fd may not be implemented on your platform.\n\
6686 If it is unavailable, using it will raise a NotImplementedError.");
6687
6688#if defined(MS_WINDOWS)
6689
6690/* Grab CreateSymbolicLinkW dynamically from kernel32 */
6691static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
6692static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
6693static int
6694check_CreateSymbolicLink()
6695{
6696 HINSTANCE hKernel32;
6697 /* only recheck */
6698 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
6699 return 1;
6700 hKernel32 = GetModuleHandleW(L"KERNEL32");
6701 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
6702 "CreateSymbolicLinkW");
6703 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
6704 "CreateSymbolicLinkA");
6705 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
6706}
6707
6708#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006709
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006710static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006711posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006712{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006713 path_t src;
6714 path_t dst;
6715 int dir_fd = DEFAULT_DIR_FD;
6716 int target_is_directory = 0;
6717 static char *keywords[] = {"src", "dst", "target_is_directory",
6718 "dir_fd", NULL};
6719 PyObject *return_value;
6720#ifdef MS_WINDOWS
6721 DWORD result;
6722#else
6723 int result;
6724#endif
6725
6726 memset(&src, 0, sizeof(src));
Victor Stinner292c8352012-10-30 02:17:38 +01006727 src.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07006728 src.argument_name = "src";
6729 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01006730 dst.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07006731 dst.argument_name = "dst";
6732
6733#ifdef MS_WINDOWS
6734 if (!check_CreateSymbolicLink()) {
6735 PyErr_SetString(PyExc_NotImplementedError,
6736 "CreateSymbolicLink functions not found");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03006737 return NULL;
6738 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07006739 if (!win32_can_symlink) {
6740 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03006741 return NULL;
6742 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07006743#endif
6744
6745 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
6746 keywords,
6747 path_converter, &src,
6748 path_converter, &dst,
6749 &target_is_directory,
6750#ifdef HAVE_SYMLINKAT
6751 dir_fd_converter, &dir_fd
6752#else
6753 dir_fd_unavailable, &dir_fd
6754#endif
6755 ))
6756 return NULL;
6757
6758 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
6759 PyErr_SetString(PyExc_ValueError,
6760 "symlink: src and dst must be the same type");
6761 return_value = NULL;
6762 goto exit;
6763 }
6764
6765#ifdef MS_WINDOWS
6766 Py_BEGIN_ALLOW_THREADS
6767 if (dst.wide)
6768 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
6769 target_is_directory);
6770 else
6771 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
6772 target_is_directory);
6773 Py_END_ALLOW_THREADS
6774
6775 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01006776 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006777 goto exit;
6778 }
6779
6780#else
6781
6782 Py_BEGIN_ALLOW_THREADS
6783#if HAVE_SYMLINKAT
6784 if (dir_fd != DEFAULT_DIR_FD)
6785 result = symlinkat(src.narrow, dir_fd, dst.narrow);
6786 else
6787#endif
6788 result = symlink(src.narrow, dst.narrow);
6789 Py_END_ALLOW_THREADS
6790
6791 if (result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01006792 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006793 goto exit;
6794 }
6795#endif
6796
6797 return_value = Py_None;
6798 Py_INCREF(Py_None);
6799 goto exit; /* silence "unused label" warning */
6800exit:
6801 path_cleanup(&src);
6802 path_cleanup(&dst);
6803 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006804}
Larry Hastings9cf065c2012-06-22 16:30:09 -07006805
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006806#endif /* HAVE_SYMLINK */
6807
Larry Hastings9cf065c2012-06-22 16:30:09 -07006808
Brian Curtind40e6f72010-07-08 21:39:08 +00006809#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
6810
Brian Curtind40e6f72010-07-08 21:39:08 +00006811static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006812win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00006813{
6814 wchar_t *path;
6815 DWORD n_bytes_returned;
6816 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006817 PyObject *po, *result;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03006818 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00006819 HANDLE reparse_point_handle;
6820
6821 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
6822 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
6823 wchar_t *print_name;
6824
Larry Hastings9cf065c2012-06-22 16:30:09 -07006825 static char *keywords[] = {"path", "dir_fd", NULL};
6826
6827 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
6828 &po,
6829 dir_fd_unavailable, &dir_fd
6830 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02006831 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07006832
Victor Stinnereb5657a2011-09-30 01:44:27 +02006833 path = PyUnicode_AsUnicode(po);
6834 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00006835 return NULL;
6836
6837 /* First get a handle to the reparse point */
6838 Py_BEGIN_ALLOW_THREADS
6839 reparse_point_handle = CreateFileW(
6840 path,
6841 0,
6842 0,
6843 0,
6844 OPEN_EXISTING,
6845 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
6846 0);
6847 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006848
Brian Curtind40e6f72010-07-08 21:39:08 +00006849 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006850 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006851
Brian Curtind40e6f72010-07-08 21:39:08 +00006852 Py_BEGIN_ALLOW_THREADS
6853 /* New call DeviceIoControl to read the reparse point */
6854 io_result = DeviceIoControl(
6855 reparse_point_handle,
6856 FSCTL_GET_REPARSE_POINT,
6857 0, 0, /* in buffer */
6858 target_buffer, sizeof(target_buffer),
6859 &n_bytes_returned,
6860 0 /* we're not using OVERLAPPED_IO */
6861 );
6862 CloseHandle(reparse_point_handle);
6863 Py_END_ALLOW_THREADS
6864
6865 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006866 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00006867
6868 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
6869 {
6870 PyErr_SetString(PyExc_ValueError,
6871 "not a symbolic link");
6872 return NULL;
6873 }
Brian Curtin74e45612010-07-09 15:58:59 +00006874 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
6875 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
6876
6877 result = PyUnicode_FromWideChar(print_name,
6878 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00006879 return result;
6880}
6881
6882#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
6883
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006884
Larry Hastings605a62d2012-06-24 04:33:36 -07006885static PyStructSequence_Field times_result_fields[] = {
6886 {"user", "user time"},
6887 {"system", "system time"},
6888 {"children_user", "user time of children"},
6889 {"children_system", "system time of children"},
6890 {"elapsed", "elapsed time since an arbitrary point in the past"},
6891 {NULL}
6892};
6893
6894PyDoc_STRVAR(times_result__doc__,
6895"times_result: Result from os.times().\n\n\
6896This object may be accessed either as a tuple of\n\
6897 (user, system, children_user, children_system, elapsed),\n\
6898or via the attributes user, system, children_user, children_system,\n\
6899and elapsed.\n\
6900\n\
6901See os.times for more information.");
6902
6903static PyStructSequence_Desc times_result_desc = {
6904 "times_result", /* name */
6905 times_result__doc__, /* doc */
6906 times_result_fields,
6907 5
6908};
6909
6910static PyTypeObject TimesResultType;
6911
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006912#ifdef MS_WINDOWS
6913#define HAVE_TIMES /* mandatory, for the method table */
6914#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07006915
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006916#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07006917
6918static PyObject *
6919build_times_result(double user, double system,
6920 double children_user, double children_system,
6921 double elapsed)
6922{
6923 PyObject *value = PyStructSequence_New(&TimesResultType);
6924 if (value == NULL)
6925 return NULL;
6926
6927#define SET(i, field) \
6928 { \
6929 PyObject *o = PyFloat_FromDouble(field); \
6930 if (!o) { \
6931 Py_DECREF(value); \
6932 return NULL; \
6933 } \
6934 PyStructSequence_SET_ITEM(value, i, o); \
6935 } \
6936
6937 SET(0, user);
6938 SET(1, system);
6939 SET(2, children_user);
6940 SET(3, children_system);
6941 SET(4, elapsed);
6942
6943#undef SET
6944
6945 return value;
6946}
6947
6948PyDoc_STRVAR(posix_times__doc__,
6949"times() -> times_result\n\n\
6950Return an object containing floating point numbers indicating process\n\
6951times. The object behaves like a named tuple with these fields:\n\
6952 (utime, stime, cutime, cstime, elapsed_time)");
6953
Jesus Ceaab70e2a2012-10-05 01:48:08 +02006954#if defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00006955static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006956posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006957{
Victor Stinner8c62be82010-05-06 00:08:46 +00006958 FILETIME create, exit, kernel, user;
6959 HANDLE hProc;
6960 hProc = GetCurrentProcess();
6961 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6962 /* The fields of a FILETIME structure are the hi and lo part
6963 of a 64-bit value expressed in 100 nanosecond units.
6964 1e7 is one second in such units; 1e-7 the inverse.
6965 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6966 */
Larry Hastings605a62d2012-06-24 04:33:36 -07006967 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00006968 (double)(user.dwHighDateTime*429.4967296 +
6969 user.dwLowDateTime*1e-7),
6970 (double)(kernel.dwHighDateTime*429.4967296 +
6971 kernel.dwLowDateTime*1e-7),
6972 (double)0,
6973 (double)0,
6974 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006975}
Jesus Ceaab70e2a2012-10-05 01:48:08 +02006976#else /* Not Windows */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006977#define NEED_TICKS_PER_SECOND
6978static long ticks_per_second = -1;
6979static PyObject *
6980posix_times(PyObject *self, PyObject *noargs)
6981{
6982 struct tms t;
6983 clock_t c;
6984 errno = 0;
6985 c = times(&t);
6986 if (c == (clock_t) -1)
6987 return posix_error();
6988 return build_times_result(
6989 (double)t.tms_utime / ticks_per_second,
6990 (double)t.tms_stime / ticks_per_second,
6991 (double)t.tms_cutime / ticks_per_second,
6992 (double)t.tms_cstime / ticks_per_second,
6993 (double)c / ticks_per_second);
6994}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006995#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006996
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006997#endif /* HAVE_TIMES */
6998
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006999
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007000#ifdef HAVE_GETSID
7001PyDoc_STRVAR(posix_getsid__doc__,
7002"getsid(pid) -> sid\n\n\
7003Call the system call getsid().");
7004
7005static PyObject *
7006posix_getsid(PyObject *self, PyObject *args)
7007{
Victor Stinner8c62be82010-05-06 00:08:46 +00007008 pid_t pid;
7009 int sid;
7010 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7011 return NULL;
7012 sid = getsid(pid);
7013 if (sid < 0)
7014 return posix_error();
7015 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007016}
7017#endif /* HAVE_GETSID */
7018
7019
Guido van Rossumb6775db1994-08-01 11:34:53 +00007020#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007021PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007022"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007023Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007024
Barry Warsaw53699e91996-12-10 23:23:01 +00007025static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007026posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007027{
Victor Stinner8c62be82010-05-06 00:08:46 +00007028 if (setsid() < 0)
7029 return posix_error();
7030 Py_INCREF(Py_None);
7031 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007032}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007033#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007034
Guido van Rossumb6775db1994-08-01 11:34:53 +00007035#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007036PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007037"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007038Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007039
Barry Warsaw53699e91996-12-10 23:23:01 +00007040static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007041posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007042{
Victor Stinner8c62be82010-05-06 00:08:46 +00007043 pid_t pid;
7044 int pgrp;
7045 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7046 return NULL;
7047 if (setpgid(pid, pgrp) < 0)
7048 return posix_error();
7049 Py_INCREF(Py_None);
7050 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007051}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007052#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007053
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007054
Guido van Rossumb6775db1994-08-01 11:34:53 +00007055#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007056PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007057"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007058Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007059
Barry Warsaw53699e91996-12-10 23:23:01 +00007060static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007061posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007062{
Victor Stinner8c62be82010-05-06 00:08:46 +00007063 int fd;
7064 pid_t pgid;
7065 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7066 return NULL;
7067 pgid = tcgetpgrp(fd);
7068 if (pgid < 0)
7069 return posix_error();
7070 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007071}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007072#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007073
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007074
Guido van Rossumb6775db1994-08-01 11:34:53 +00007075#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007076PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007077"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007078Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007079
Barry Warsaw53699e91996-12-10 23:23:01 +00007080static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007081posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007082{
Victor Stinner8c62be82010-05-06 00:08:46 +00007083 int fd;
7084 pid_t pgid;
7085 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7086 return NULL;
7087 if (tcsetpgrp(fd, pgid) < 0)
7088 return posix_error();
7089 Py_INCREF(Py_None);
7090 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007091}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007092#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007093
Guido van Rossum687dd131993-05-17 08:34:16 +00007094/* Functions acting on file descriptors */
7095
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007096PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007097"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7098Open a file for low level IO. Returns a file handle (integer).\n\
7099\n\
7100If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7101 and path should be relative; path will then be relative to that directory.\n\
7102dir_fd may not be implemented on your platform.\n\
7103 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007104
Barry Warsaw53699e91996-12-10 23:23:01 +00007105static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007106posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007107{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007108 path_t path;
7109 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007110 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007111 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007112 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007113 PyObject *return_value = NULL;
7114 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007115
Larry Hastings9cf065c2012-06-22 16:30:09 -07007116 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007117 path.function_name = "open";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007118 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7119 path_converter, &path,
7120 &flags, &mode,
7121#ifdef HAVE_OPENAT
7122 dir_fd_converter, &dir_fd
7123#else
7124 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007125#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007126 ))
7127 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007128
Victor Stinner8c62be82010-05-06 00:08:46 +00007129 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007130#ifdef MS_WINDOWS
7131 if (path.wide)
7132 fd = _wopen(path.wide, flags, mode);
7133 else
7134#endif
7135#ifdef HAVE_OPENAT
7136 if (dir_fd != DEFAULT_DIR_FD)
7137 fd = openat(dir_fd, path.narrow, flags, mode);
7138 else
7139#endif
7140 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007141 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007142
Larry Hastings9cf065c2012-06-22 16:30:09 -07007143 if (fd == -1) {
Victor Stinner4e7d2d42012-11-05 01:20:58 +01007144 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path.object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007145 goto exit;
7146 }
7147
7148 return_value = PyLong_FromLong((long)fd);
7149
7150exit:
7151 path_cleanup(&path);
7152 return return_value;
7153}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007154
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007155PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007156"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007157Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007158
Barry Warsaw53699e91996-12-10 23:23:01 +00007159static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007160posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007161{
Victor Stinner8c62be82010-05-06 00:08:46 +00007162 int fd, res;
7163 if (!PyArg_ParseTuple(args, "i:close", &fd))
7164 return NULL;
7165 if (!_PyVerify_fd(fd))
7166 return posix_error();
7167 Py_BEGIN_ALLOW_THREADS
7168 res = close(fd);
7169 Py_END_ALLOW_THREADS
7170 if (res < 0)
7171 return posix_error();
7172 Py_INCREF(Py_None);
7173 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007174}
7175
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007176
Victor Stinner8c62be82010-05-06 00:08:46 +00007177PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007178"closerange(fd_low, fd_high)\n\n\
7179Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7180
7181static PyObject *
7182posix_closerange(PyObject *self, PyObject *args)
7183{
Victor Stinner8c62be82010-05-06 00:08:46 +00007184 int fd_from, fd_to, i;
7185 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7186 return NULL;
7187 Py_BEGIN_ALLOW_THREADS
7188 for (i = fd_from; i < fd_to; i++)
7189 if (_PyVerify_fd(i))
7190 close(i);
7191 Py_END_ALLOW_THREADS
7192 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007193}
7194
7195
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007196PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007197"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007198Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007199
Barry Warsaw53699e91996-12-10 23:23:01 +00007200static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007201posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007202{
Victor Stinner8c62be82010-05-06 00:08:46 +00007203 int fd;
7204 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7205 return NULL;
7206 if (!_PyVerify_fd(fd))
7207 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007208 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007209 if (fd < 0)
7210 return posix_error();
7211 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007212}
7213
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007214
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007215PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007216"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007217Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007218
Barry Warsaw53699e91996-12-10 23:23:01 +00007219static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007220posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007221{
Victor Stinner8c62be82010-05-06 00:08:46 +00007222 int fd, fd2, res;
7223 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
7224 return NULL;
7225 if (!_PyVerify_fd_dup2(fd, fd2))
7226 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007227 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00007228 if (res < 0)
7229 return posix_error();
7230 Py_INCREF(Py_None);
7231 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007232}
7233
Ross Lagerwall7807c352011-03-17 20:20:30 +02007234#ifdef HAVE_LOCKF
7235PyDoc_STRVAR(posix_lockf__doc__,
7236"lockf(fd, cmd, len)\n\n\
7237Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7238fd is an open file descriptor.\n\
7239cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7240F_TEST.\n\
7241len specifies the section of the file to lock.");
7242
7243static PyObject *
7244posix_lockf(PyObject *self, PyObject *args)
7245{
7246 int fd, cmd, res;
7247 off_t len;
7248 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7249 &fd, &cmd, _parse_off_t, &len))
7250 return NULL;
7251
7252 Py_BEGIN_ALLOW_THREADS
7253 res = lockf(fd, cmd, len);
7254 Py_END_ALLOW_THREADS
7255
7256 if (res < 0)
7257 return posix_error();
7258
7259 Py_RETURN_NONE;
7260}
7261#endif
7262
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007263
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007264PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007265"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007266Set the current position of a file descriptor.\n\
7267Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007268
Barry Warsaw53699e91996-12-10 23:23:01 +00007269static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007270posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007271{
Victor Stinner8c62be82010-05-06 00:08:46 +00007272 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007273#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007274 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007275#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007276 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007277#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007278 PyObject *posobj;
7279 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007280 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007281#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007282 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7283 switch (how) {
7284 case 0: how = SEEK_SET; break;
7285 case 1: how = SEEK_CUR; break;
7286 case 2: how = SEEK_END; break;
7287 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007288#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007289
Ross Lagerwall8e749672011-03-17 21:54:07 +02007290#if !defined(HAVE_LARGEFILE_SUPPORT)
7291 pos = PyLong_AsLong(posobj);
7292#else
7293 pos = PyLong_AsLongLong(posobj);
7294#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007295 if (PyErr_Occurred())
7296 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007297
Victor Stinner8c62be82010-05-06 00:08:46 +00007298 if (!_PyVerify_fd(fd))
7299 return posix_error();
7300 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007301#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007302 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007303#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007304 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007305#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007306 Py_END_ALLOW_THREADS
7307 if (res < 0)
7308 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007309
7310#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007311 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007312#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007313 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007314#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007315}
7316
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007317
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007318PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007319"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007320Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007321
Barry Warsaw53699e91996-12-10 23:23:01 +00007322static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007323posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007324{
Victor Stinner8c62be82010-05-06 00:08:46 +00007325 int fd, size;
7326 Py_ssize_t n;
7327 PyObject *buffer;
7328 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7329 return NULL;
7330 if (size < 0) {
7331 errno = EINVAL;
7332 return posix_error();
7333 }
7334 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7335 if (buffer == NULL)
7336 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007337 if (!_PyVerify_fd(fd)) {
7338 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007339 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007340 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007341 Py_BEGIN_ALLOW_THREADS
7342 n = read(fd, PyBytes_AS_STRING(buffer), size);
7343 Py_END_ALLOW_THREADS
7344 if (n < 0) {
7345 Py_DECREF(buffer);
7346 return posix_error();
7347 }
7348 if (n != size)
7349 _PyBytes_Resize(&buffer, n);
7350 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007351}
7352
Ross Lagerwall7807c352011-03-17 20:20:30 +02007353#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7354 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007355static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007356iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7357{
7358 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007359 Py_ssize_t blen, total = 0;
7360
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007361 *iov = PyMem_New(struct iovec, cnt);
7362 if (*iov == NULL) {
7363 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007364 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007365 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007366
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007367 *buf = PyMem_New(Py_buffer, cnt);
7368 if (*buf == NULL) {
7369 PyMem_Del(*iov);
7370 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007371 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007372 }
7373
7374 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007375 PyObject *item = PySequence_GetItem(seq, i);
7376 if (item == NULL)
7377 goto fail;
7378 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7379 Py_DECREF(item);
7380 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007381 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007382 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007383 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007384 blen = (*buf)[i].len;
7385 (*iov)[i].iov_len = blen;
7386 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007387 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007388 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007389
7390fail:
7391 PyMem_Del(*iov);
7392 for (j = 0; j < i; j++) {
7393 PyBuffer_Release(&(*buf)[j]);
7394 }
7395 PyMem_Del(*buf);
7396 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007397}
7398
7399static void
7400iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7401{
7402 int i;
7403 PyMem_Del(iov);
7404 for (i = 0; i < cnt; i++) {
7405 PyBuffer_Release(&buf[i]);
7406 }
7407 PyMem_Del(buf);
7408}
7409#endif
7410
Ross Lagerwall7807c352011-03-17 20:20:30 +02007411#ifdef HAVE_READV
7412PyDoc_STRVAR(posix_readv__doc__,
7413"readv(fd, buffers) -> bytesread\n\n\
7414Read from a file descriptor into a number of writable buffers. buffers\n\
7415is an arbitrary sequence of writable buffers.\n\
7416Returns the total number of bytes read.");
7417
7418static PyObject *
7419posix_readv(PyObject *self, PyObject *args)
7420{
7421 int fd, cnt;
7422 Py_ssize_t n;
7423 PyObject *seq;
7424 struct iovec *iov;
7425 Py_buffer *buf;
7426
7427 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7428 return NULL;
7429 if (!PySequence_Check(seq)) {
7430 PyErr_SetString(PyExc_TypeError,
7431 "readv() arg 2 must be a sequence");
7432 return NULL;
7433 }
7434 cnt = PySequence_Size(seq);
7435
7436 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7437 return NULL;
7438
7439 Py_BEGIN_ALLOW_THREADS
7440 n = readv(fd, iov, cnt);
7441 Py_END_ALLOW_THREADS
7442
7443 iov_cleanup(iov, buf, cnt);
7444 return PyLong_FromSsize_t(n);
7445}
7446#endif
7447
7448#ifdef HAVE_PREAD
7449PyDoc_STRVAR(posix_pread__doc__,
7450"pread(fd, buffersize, offset) -> string\n\n\
7451Read from a file descriptor, fd, at a position of offset. It will read up\n\
7452to buffersize number of bytes. The file offset remains unchanged.");
7453
7454static PyObject *
7455posix_pread(PyObject *self, PyObject *args)
7456{
7457 int fd, size;
7458 off_t offset;
7459 Py_ssize_t n;
7460 PyObject *buffer;
7461 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7462 return NULL;
7463
7464 if (size < 0) {
7465 errno = EINVAL;
7466 return posix_error();
7467 }
7468 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7469 if (buffer == NULL)
7470 return NULL;
7471 if (!_PyVerify_fd(fd)) {
7472 Py_DECREF(buffer);
7473 return posix_error();
7474 }
7475 Py_BEGIN_ALLOW_THREADS
7476 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7477 Py_END_ALLOW_THREADS
7478 if (n < 0) {
7479 Py_DECREF(buffer);
7480 return posix_error();
7481 }
7482 if (n != size)
7483 _PyBytes_Resize(&buffer, n);
7484 return buffer;
7485}
7486#endif
7487
7488PyDoc_STRVAR(posix_write__doc__,
7489"write(fd, string) -> byteswritten\n\n\
7490Write a string to a file descriptor.");
7491
7492static PyObject *
7493posix_write(PyObject *self, PyObject *args)
7494{
7495 Py_buffer pbuf;
7496 int fd;
7497 Py_ssize_t size, len;
7498
7499 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
7500 return NULL;
7501 if (!_PyVerify_fd(fd)) {
7502 PyBuffer_Release(&pbuf);
7503 return posix_error();
7504 }
7505 len = pbuf.len;
7506 Py_BEGIN_ALLOW_THREADS
7507#if defined(MS_WIN64) || defined(MS_WINDOWS)
7508 if (len > INT_MAX)
7509 len = INT_MAX;
7510 size = write(fd, pbuf.buf, (int)len);
7511#else
7512 size = write(fd, pbuf.buf, len);
7513#endif
7514 Py_END_ALLOW_THREADS
7515 PyBuffer_Release(&pbuf);
7516 if (size < 0)
7517 return posix_error();
7518 return PyLong_FromSsize_t(size);
7519}
7520
7521#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007522PyDoc_STRVAR(posix_sendfile__doc__,
7523"sendfile(out, in, offset, nbytes) -> byteswritten\n\
7524sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
7525 -> byteswritten\n\
7526Copy nbytes bytes from file descriptor in to file descriptor out.");
7527
7528static PyObject *
7529posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
7530{
7531 int in, out;
7532 Py_ssize_t ret;
7533 off_t offset;
7534
7535#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
7536#ifndef __APPLE__
7537 Py_ssize_t len;
7538#endif
7539 PyObject *headers = NULL, *trailers = NULL;
7540 Py_buffer *hbuf, *tbuf;
7541 off_t sbytes;
7542 struct sf_hdtr sf;
7543 int flags = 0;
7544 sf.headers = NULL;
7545 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00007546 static char *keywords[] = {"out", "in",
7547 "offset", "count",
7548 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007549
7550#ifdef __APPLE__
7551 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007552 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007553#else
7554 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007555 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007556#endif
7557 &headers, &trailers, &flags))
7558 return NULL;
7559 if (headers != NULL) {
7560 if (!PySequence_Check(headers)) {
7561 PyErr_SetString(PyExc_TypeError,
7562 "sendfile() headers must be a sequence or None");
7563 return NULL;
7564 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007565 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007566 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007567 if (sf.hdr_cnt > 0 &&
7568 !(i = iov_setup(&(sf.headers), &hbuf,
7569 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007570 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007571#ifdef __APPLE__
7572 sbytes += i;
7573#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007574 }
7575 }
7576 if (trailers != NULL) {
7577 if (!PySequence_Check(trailers)) {
7578 PyErr_SetString(PyExc_TypeError,
7579 "sendfile() trailers must be a sequence or None");
7580 return NULL;
7581 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007582 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007583 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007584 if (sf.trl_cnt > 0 &&
7585 !(i = iov_setup(&(sf.trailers), &tbuf,
7586 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007587 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007588#ifdef __APPLE__
7589 sbytes += i;
7590#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007591 }
7592 }
7593
7594 Py_BEGIN_ALLOW_THREADS
7595#ifdef __APPLE__
7596 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
7597#else
7598 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
7599#endif
7600 Py_END_ALLOW_THREADS
7601
7602 if (sf.headers != NULL)
7603 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
7604 if (sf.trailers != NULL)
7605 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
7606
7607 if (ret < 0) {
7608 if ((errno == EAGAIN) || (errno == EBUSY)) {
7609 if (sbytes != 0) {
7610 // some data has been sent
7611 goto done;
7612 }
7613 else {
7614 // no data has been sent; upper application is supposed
7615 // to retry on EAGAIN or EBUSY
7616 return posix_error();
7617 }
7618 }
7619 return posix_error();
7620 }
7621 goto done;
7622
7623done:
7624 #if !defined(HAVE_LARGEFILE_SUPPORT)
7625 return Py_BuildValue("l", sbytes);
7626 #else
7627 return Py_BuildValue("L", sbytes);
7628 #endif
7629
7630#else
7631 Py_ssize_t count;
7632 PyObject *offobj;
7633 static char *keywords[] = {"out", "in",
7634 "offset", "count", NULL};
7635 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
7636 keywords, &out, &in, &offobj, &count))
7637 return NULL;
7638#ifdef linux
7639 if (offobj == Py_None) {
7640 Py_BEGIN_ALLOW_THREADS
7641 ret = sendfile(out, in, NULL, count);
7642 Py_END_ALLOW_THREADS
7643 if (ret < 0)
7644 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02007645 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007646 }
7647#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00007648 if (!_parse_off_t(offobj, &offset))
7649 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007650 Py_BEGIN_ALLOW_THREADS
7651 ret = sendfile(out, in, &offset, count);
7652 Py_END_ALLOW_THREADS
7653 if (ret < 0)
7654 return posix_error();
7655 return Py_BuildValue("n", ret);
7656#endif
7657}
7658#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007659
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007660PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007661"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07007662Like stat(), but for an open file descriptor.\n\
7663Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007664
Barry Warsaw53699e91996-12-10 23:23:01 +00007665static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007666posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007667{
Victor Stinner8c62be82010-05-06 00:08:46 +00007668 int fd;
7669 STRUCT_STAT st;
7670 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01007671 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007672 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007673#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00007674 /* on OpenVMS we must ensure that all bytes are written to the file */
7675 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007676#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007677 Py_BEGIN_ALLOW_THREADS
7678 res = FSTAT(fd, &st);
7679 Py_END_ALLOW_THREADS
7680 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00007681#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01007682 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00007683#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007684 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00007685#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007686 }
Tim Peters5aa91602002-01-30 05:46:57 +00007687
Victor Stinner4195b5c2012-02-08 23:03:19 +01007688 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00007689}
7690
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007691PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007692"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007693Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007694connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00007695
7696static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00007697posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00007698{
Victor Stinner8c62be82010-05-06 00:08:46 +00007699 int fd;
7700 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
7701 return NULL;
7702 if (!_PyVerify_fd(fd))
7703 return PyBool_FromLong(0);
7704 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00007705}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007706
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007707#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007708PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007709"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007710Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007711
Barry Warsaw53699e91996-12-10 23:23:01 +00007712static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007713posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007714{
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007715#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007716 int fds[2];
7717 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007718 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00007719 if (res != 0)
7720 return posix_error();
7721 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007722#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007723 HANDLE read, write;
7724 int read_fd, write_fd;
7725 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00007726 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00007727 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01007728 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00007729 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
7730 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
7731 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007732#endif /* MS_WINDOWS */
Guido van Rossum687dd131993-05-17 08:34:16 +00007733}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007734#endif /* HAVE_PIPE */
7735
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007736#ifdef HAVE_PIPE2
7737PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02007738"pipe2(flags) -> (read_end, write_end)\n\n\
7739Create a pipe with flags set atomically.\n\
7740flags can be constructed by ORing together one or more of these values:\n\
7741O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007742");
7743
7744static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02007745posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007746{
Charles-François Natali368f34b2011-06-06 19:49:47 +02007747 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007748 int fds[2];
7749 int res;
7750
Serhiy Storchaka78980432013-01-15 01:12:17 +02007751 flags = _PyLong_AsInt(arg);
Charles-François Natali368f34b2011-06-06 19:49:47 +02007752 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007753 return NULL;
7754
7755 res = pipe2(fds, flags);
7756 if (res != 0)
7757 return posix_error();
7758 return Py_BuildValue("(ii)", fds[0], fds[1]);
7759}
7760#endif /* HAVE_PIPE2 */
7761
Ross Lagerwall7807c352011-03-17 20:20:30 +02007762#ifdef HAVE_WRITEV
7763PyDoc_STRVAR(posix_writev__doc__,
7764"writev(fd, buffers) -> byteswritten\n\n\
7765Write the contents of buffers to a file descriptor, where buffers is an\n\
7766arbitrary sequence of buffers.\n\
7767Returns the total bytes written.");
7768
7769static PyObject *
7770posix_writev(PyObject *self, PyObject *args)
7771{
7772 int fd, cnt;
7773 Py_ssize_t res;
7774 PyObject *seq;
7775 struct iovec *iov;
7776 Py_buffer *buf;
7777 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
7778 return NULL;
7779 if (!PySequence_Check(seq)) {
7780 PyErr_SetString(PyExc_TypeError,
7781 "writev() arg 2 must be a sequence");
7782 return NULL;
7783 }
7784 cnt = PySequence_Size(seq);
7785
7786 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
7787 return NULL;
7788 }
7789
7790 Py_BEGIN_ALLOW_THREADS
7791 res = writev(fd, iov, cnt);
7792 Py_END_ALLOW_THREADS
7793
7794 iov_cleanup(iov, buf, cnt);
7795 return PyLong_FromSsize_t(res);
7796}
7797#endif
7798
7799#ifdef HAVE_PWRITE
7800PyDoc_STRVAR(posix_pwrite__doc__,
7801"pwrite(fd, string, offset) -> byteswritten\n\n\
7802Write string to a file descriptor, fd, from offset, leaving the file\n\
7803offset unchanged.");
7804
7805static PyObject *
7806posix_pwrite(PyObject *self, PyObject *args)
7807{
7808 Py_buffer pbuf;
7809 int fd;
7810 off_t offset;
7811 Py_ssize_t size;
7812
7813 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
7814 return NULL;
7815
7816 if (!_PyVerify_fd(fd)) {
7817 PyBuffer_Release(&pbuf);
7818 return posix_error();
7819 }
7820 Py_BEGIN_ALLOW_THREADS
7821 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
7822 Py_END_ALLOW_THREADS
7823 PyBuffer_Release(&pbuf);
7824 if (size < 0)
7825 return posix_error();
7826 return PyLong_FromSsize_t(size);
7827}
7828#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007829
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007830#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007831PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007832"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
7833Create a FIFO (a POSIX named pipe).\n\
7834\n\
7835If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7836 and path should be relative; path will then be relative to that directory.\n\
7837dir_fd may not be implemented on your platform.\n\
7838 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007839
Barry Warsaw53699e91996-12-10 23:23:01 +00007840static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007841posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007842{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007843 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00007844 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007845 int dir_fd = DEFAULT_DIR_FD;
7846 int result;
7847 PyObject *return_value = NULL;
7848 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
7849
7850 memset(&path, 0, sizeof(path));
7851 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
7852 path_converter, &path,
7853 &mode,
7854#ifdef HAVE_MKFIFOAT
7855 dir_fd_converter, &dir_fd
7856#else
7857 dir_fd_unavailable, &dir_fd
7858#endif
7859 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007860 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007861
Victor Stinner8c62be82010-05-06 00:08:46 +00007862 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007863#ifdef HAVE_MKFIFOAT
7864 if (dir_fd != DEFAULT_DIR_FD)
7865 result = mkfifoat(dir_fd, path.narrow, mode);
7866 else
7867#endif
7868 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007869 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007870
7871 if (result < 0) {
7872 return_value = posix_error();
7873 goto exit;
7874 }
7875
7876 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00007877 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007878
7879exit:
7880 path_cleanup(&path);
7881 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007882}
7883#endif
7884
Neal Norwitz11690112002-07-30 01:08:28 +00007885#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007886PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007887"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007888Create a filesystem node (file, device special file or named pipe)\n\
7889named filename. mode specifies both the permissions to use and the\n\
7890type of node to be created, being combined (bitwise OR) with one of\n\
7891S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007892device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07007893os.makedev()), otherwise it is ignored.\n\
7894\n\
7895If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7896 and path should be relative; path will then be relative to that directory.\n\
7897dir_fd may not be implemented on your platform.\n\
7898 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007899
7900
7901static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007902posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007903{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007904 path_t path;
7905 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00007906 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007907 int dir_fd = DEFAULT_DIR_FD;
7908 int result;
7909 PyObject *return_value = NULL;
7910 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
7911
7912 memset(&path, 0, sizeof(path));
7913 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
7914 path_converter, &path,
7915 &mode, &device,
7916#ifdef HAVE_MKNODAT
7917 dir_fd_converter, &dir_fd
7918#else
7919 dir_fd_unavailable, &dir_fd
7920#endif
7921 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007922 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007923
Victor Stinner8c62be82010-05-06 00:08:46 +00007924 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007925#ifdef HAVE_MKNODAT
7926 if (dir_fd != DEFAULT_DIR_FD)
7927 result = mknodat(dir_fd, path.narrow, mode, device);
7928 else
7929#endif
7930 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00007931 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007932
7933 if (result < 0) {
7934 return_value = posix_error();
7935 goto exit;
7936 }
7937
7938 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00007939 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02007940
Larry Hastings9cf065c2012-06-22 16:30:09 -07007941exit:
7942 path_cleanup(&path);
7943 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007944}
7945#endif
7946
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007947#ifdef HAVE_DEVICE_MACROS
7948PyDoc_STRVAR(posix_major__doc__,
7949"major(device) -> major number\n\
7950Extracts a device major number from a raw device number.");
7951
7952static PyObject *
7953posix_major(PyObject *self, PyObject *args)
7954{
Victor Stinner8c62be82010-05-06 00:08:46 +00007955 int device;
7956 if (!PyArg_ParseTuple(args, "i:major", &device))
7957 return NULL;
7958 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007959}
7960
7961PyDoc_STRVAR(posix_minor__doc__,
7962"minor(device) -> minor number\n\
7963Extracts a device minor number from a raw device number.");
7964
7965static PyObject *
7966posix_minor(PyObject *self, PyObject *args)
7967{
Victor Stinner8c62be82010-05-06 00:08:46 +00007968 int device;
7969 if (!PyArg_ParseTuple(args, "i:minor", &device))
7970 return NULL;
7971 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007972}
7973
7974PyDoc_STRVAR(posix_makedev__doc__,
7975"makedev(major, minor) -> device number\n\
7976Composes a raw device number from the major and minor device numbers.");
7977
7978static PyObject *
7979posix_makedev(PyObject *self, PyObject *args)
7980{
Victor Stinner8c62be82010-05-06 00:08:46 +00007981 int major, minor;
7982 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
7983 return NULL;
7984 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007985}
7986#endif /* device macros */
7987
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007988
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007989#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007990PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007991"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007992Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007993
Barry Warsaw53699e91996-12-10 23:23:01 +00007994static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007995posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007996{
Victor Stinner8c62be82010-05-06 00:08:46 +00007997 int fd;
7998 off_t length;
7999 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008000
Ross Lagerwall7807c352011-03-17 20:20:30 +02008001 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008002 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008003
Victor Stinner8c62be82010-05-06 00:08:46 +00008004 Py_BEGIN_ALLOW_THREADS
8005 res = ftruncate(fd, length);
8006 Py_END_ALLOW_THREADS
8007 if (res < 0)
8008 return posix_error();
8009 Py_INCREF(Py_None);
8010 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008011}
8012#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008013
Ross Lagerwall7807c352011-03-17 20:20:30 +02008014#ifdef HAVE_TRUNCATE
8015PyDoc_STRVAR(posix_truncate__doc__,
8016"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008017Truncate the file given by path to length bytes.\n\
8018On some platforms, path may also be specified as an open file descriptor.\n\
8019 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008020
8021static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008022posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008023{
Georg Brandl306336b2012-06-24 12:55:33 +02008024 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008025 off_t length;
8026 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008027 PyObject *result = NULL;
8028 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008029
Georg Brandl306336b2012-06-24 12:55:33 +02008030 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008031 path.function_name = "truncate";
Georg Brandl306336b2012-06-24 12:55:33 +02008032#ifdef HAVE_FTRUNCATE
8033 path.allow_fd = 1;
8034#endif
8035 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8036 path_converter, &path,
8037 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008038 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008039
8040 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008041#ifdef HAVE_FTRUNCATE
8042 if (path.fd != -1)
8043 res = ftruncate(path.fd, length);
8044 else
8045#endif
8046 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008047 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008048 if (res < 0)
Victor Stinner292c8352012-10-30 02:17:38 +01008049 result = path_error(&path);
Georg Brandl306336b2012-06-24 12:55:33 +02008050 else {
8051 Py_INCREF(Py_None);
8052 result = Py_None;
8053 }
8054 path_cleanup(&path);
8055 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008056}
8057#endif
8058
8059#ifdef HAVE_POSIX_FALLOCATE
8060PyDoc_STRVAR(posix_posix_fallocate__doc__,
8061"posix_fallocate(fd, offset, len)\n\n\
8062Ensures that enough disk space is allocated for the file specified by fd\n\
8063starting from offset and continuing for len bytes.");
8064
8065static PyObject *
8066posix_posix_fallocate(PyObject *self, PyObject *args)
8067{
8068 off_t len, offset;
8069 int res, fd;
8070
8071 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8072 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8073 return NULL;
8074
8075 Py_BEGIN_ALLOW_THREADS
8076 res = posix_fallocate(fd, offset, len);
8077 Py_END_ALLOW_THREADS
8078 if (res != 0) {
8079 errno = res;
8080 return posix_error();
8081 }
8082 Py_RETURN_NONE;
8083}
8084#endif
8085
8086#ifdef HAVE_POSIX_FADVISE
8087PyDoc_STRVAR(posix_posix_fadvise__doc__,
8088"posix_fadvise(fd, offset, len, advice)\n\n\
8089Announces an intention to access data in a specific pattern thus allowing\n\
8090the kernel to make optimizations.\n\
8091The advice applies to the region of the file specified by fd starting at\n\
8092offset and continuing for len bytes.\n\
8093advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8094POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8095POSIX_FADV_DONTNEED.");
8096
8097static PyObject *
8098posix_posix_fadvise(PyObject *self, PyObject *args)
8099{
8100 off_t len, offset;
8101 int res, fd, advice;
8102
8103 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8104 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8105 return NULL;
8106
8107 Py_BEGIN_ALLOW_THREADS
8108 res = posix_fadvise(fd, offset, len, advice);
8109 Py_END_ALLOW_THREADS
8110 if (res != 0) {
8111 errno = res;
8112 return posix_error();
8113 }
8114 Py_RETURN_NONE;
8115}
8116#endif
8117
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008118#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008119PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008120"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008121Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008122
Fred Drake762e2061999-08-26 17:23:54 +00008123/* Save putenv() parameters as values here, so we can collect them when they
8124 * get re-set with another call for the same key. */
8125static PyObject *posix_putenv_garbage;
8126
Tim Peters5aa91602002-01-30 05:46:57 +00008127static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008128posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008129{
Victor Stinner84ae1182010-05-06 22:05:07 +00008130 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008131#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008132 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008133 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008134
Victor Stinner8c62be82010-05-06 00:08:46 +00008135 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008136 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008137 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008138 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008139
Victor Stinner65170952011-11-22 22:16:17 +01008140 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008141 if (newstr == NULL) {
8142 PyErr_NoMemory();
8143 goto error;
8144 }
Victor Stinner65170952011-11-22 22:16:17 +01008145 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8146 PyErr_Format(PyExc_ValueError,
8147 "the environment variable is longer than %u characters",
8148 _MAX_ENV);
8149 goto error;
8150 }
8151
Victor Stinner8c62be82010-05-06 00:08:46 +00008152 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008153 if (newenv == NULL)
8154 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008155 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008156 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008157 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008158 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008159#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008160 PyObject *os1, *os2;
8161 char *s1, *s2;
8162 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008163
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008164 if (!PyArg_ParseTuple(args,
8165 "O&O&:putenv",
8166 PyUnicode_FSConverter, &os1,
8167 PyUnicode_FSConverter, &os2))
8168 return NULL;
8169 s1 = PyBytes_AsString(os1);
8170 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008171
Victor Stinner65170952011-11-22 22:16:17 +01008172 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008173 if (newstr == NULL) {
8174 PyErr_NoMemory();
8175 goto error;
8176 }
8177
Victor Stinner8c62be82010-05-06 00:08:46 +00008178 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008179 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008180 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008181 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008182 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008183#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008184
Victor Stinner8c62be82010-05-06 00:08:46 +00008185 /* Install the first arg and newstr in posix_putenv_garbage;
8186 * this will cause previous value to be collected. This has to
8187 * happen after the real putenv() call because the old value
8188 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008189 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008190 /* really not much we can do; just leak */
8191 PyErr_Clear();
8192 }
8193 else {
8194 Py_DECREF(newstr);
8195 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008196
Martin v. Löwis011e8422009-05-05 04:43:17 +00008197#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008198 Py_DECREF(os1);
8199 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008200#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008201 Py_RETURN_NONE;
8202
8203error:
8204#ifndef MS_WINDOWS
8205 Py_DECREF(os1);
8206 Py_DECREF(os2);
8207#endif
8208 Py_XDECREF(newstr);
8209 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008210}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008211#endif /* putenv */
8212
Guido van Rossumc524d952001-10-19 01:31:59 +00008213#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008214PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008215"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008216Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008217
8218static PyObject *
8219posix_unsetenv(PyObject *self, PyObject *args)
8220{
Victor Stinner65170952011-11-22 22:16:17 +01008221 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008222#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008223 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008224#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008225
8226 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008227
Victor Stinner65170952011-11-22 22:16:17 +01008228 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008229 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008230
Victor Stinner984890f2011-11-24 13:53:38 +01008231#ifdef HAVE_BROKEN_UNSETENV
8232 unsetenv(PyBytes_AS_STRING(name));
8233#else
Victor Stinner65170952011-11-22 22:16:17 +01008234 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008235 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008236 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008237 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008238 }
Victor Stinner984890f2011-11-24 13:53:38 +01008239#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008240
Victor Stinner8c62be82010-05-06 00:08:46 +00008241 /* Remove the key from posix_putenv_garbage;
8242 * this will cause it to be collected. This has to
8243 * happen after the real unsetenv() call because the
8244 * old value was still accessible until then.
8245 */
Victor Stinner65170952011-11-22 22:16:17 +01008246 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008247 /* really not much we can do; just leak */
8248 PyErr_Clear();
8249 }
Victor Stinner65170952011-11-22 22:16:17 +01008250 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008251 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008252}
8253#endif /* unsetenv */
8254
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008255PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008256"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008257Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008258
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008259static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008260posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008261{
Victor Stinner8c62be82010-05-06 00:08:46 +00008262 int code;
8263 char *message;
8264 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8265 return NULL;
8266 message = strerror(code);
8267 if (message == NULL) {
8268 PyErr_SetString(PyExc_ValueError,
8269 "strerror() argument out of range");
8270 return NULL;
8271 }
Victor Stinner1b579672011-12-17 05:47:23 +01008272 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008273}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008274
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008275
Guido van Rossumc9641791998-08-04 15:26:23 +00008276#ifdef HAVE_SYS_WAIT_H
8277
Fred Drake106c1a02002-04-23 15:58:02 +00008278#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008279PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008280"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008281Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008282
8283static PyObject *
8284posix_WCOREDUMP(PyObject *self, PyObject *args)
8285{
Victor Stinner8c62be82010-05-06 00:08:46 +00008286 WAIT_TYPE status;
8287 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008288
Victor Stinner8c62be82010-05-06 00:08:46 +00008289 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8290 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008291
Victor Stinner8c62be82010-05-06 00:08:46 +00008292 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008293}
8294#endif /* WCOREDUMP */
8295
8296#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008297PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008298"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008299Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008300job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00008301
8302static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008303posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00008304{
Victor Stinner8c62be82010-05-06 00:08:46 +00008305 WAIT_TYPE status;
8306 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008307
Victor Stinner8c62be82010-05-06 00:08:46 +00008308 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
8309 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008310
Victor Stinner8c62be82010-05-06 00:08:46 +00008311 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008312}
8313#endif /* WIFCONTINUED */
8314
Guido van Rossumc9641791998-08-04 15:26:23 +00008315#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008316PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008317"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008318Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008319
8320static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008321posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008322{
Victor Stinner8c62be82010-05-06 00:08:46 +00008323 WAIT_TYPE status;
8324 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008325
Victor Stinner8c62be82010-05-06 00:08:46 +00008326 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
8327 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008328
Victor Stinner8c62be82010-05-06 00:08:46 +00008329 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008330}
8331#endif /* WIFSTOPPED */
8332
8333#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008334PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008335"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008336Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008337
8338static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008339posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008340{
Victor Stinner8c62be82010-05-06 00:08:46 +00008341 WAIT_TYPE status;
8342 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008343
Victor Stinner8c62be82010-05-06 00:08:46 +00008344 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8345 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008346
Victor Stinner8c62be82010-05-06 00:08:46 +00008347 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008348}
8349#endif /* WIFSIGNALED */
8350
8351#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008352PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008353"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008354Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008355system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008356
8357static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008358posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008359{
Victor Stinner8c62be82010-05-06 00:08:46 +00008360 WAIT_TYPE status;
8361 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008362
Victor Stinner8c62be82010-05-06 00:08:46 +00008363 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
8364 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008365
Victor Stinner8c62be82010-05-06 00:08:46 +00008366 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008367}
8368#endif /* WIFEXITED */
8369
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008370#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008371PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008372"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008373Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008374
8375static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008376posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008377{
Victor Stinner8c62be82010-05-06 00:08:46 +00008378 WAIT_TYPE status;
8379 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008380
Victor Stinner8c62be82010-05-06 00:08:46 +00008381 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8382 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008383
Victor Stinner8c62be82010-05-06 00:08:46 +00008384 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008385}
8386#endif /* WEXITSTATUS */
8387
8388#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008389PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008390"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008391Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008392value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008393
8394static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008395posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008396{
Victor Stinner8c62be82010-05-06 00:08:46 +00008397 WAIT_TYPE status;
8398 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008399
Victor Stinner8c62be82010-05-06 00:08:46 +00008400 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8401 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008402
Victor Stinner8c62be82010-05-06 00:08:46 +00008403 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008404}
8405#endif /* WTERMSIG */
8406
8407#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008408PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008409"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008410Return the signal that stopped the process that provided\n\
8411the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008412
8413static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008414posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008415{
Victor Stinner8c62be82010-05-06 00:08:46 +00008416 WAIT_TYPE status;
8417 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008418
Victor Stinner8c62be82010-05-06 00:08:46 +00008419 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8420 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008421
Victor Stinner8c62be82010-05-06 00:08:46 +00008422 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008423}
8424#endif /* WSTOPSIG */
8425
8426#endif /* HAVE_SYS_WAIT_H */
8427
8428
Thomas Wouters477c8d52006-05-27 19:21:47 +00008429#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00008430#ifdef _SCO_DS
8431/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
8432 needed definitions in sys/statvfs.h */
8433#define _SVID3
8434#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008435#include <sys/statvfs.h>
8436
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008437static PyObject*
8438_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008439 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8440 if (v == NULL)
8441 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008442
8443#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008444 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8445 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8446 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8447 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8448 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8449 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8450 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8451 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8452 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8453 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008454#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008455 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8456 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8457 PyStructSequence_SET_ITEM(v, 2,
8458 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8459 PyStructSequence_SET_ITEM(v, 3,
8460 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8461 PyStructSequence_SET_ITEM(v, 4,
8462 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8463 PyStructSequence_SET_ITEM(v, 5,
8464 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8465 PyStructSequence_SET_ITEM(v, 6,
8466 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8467 PyStructSequence_SET_ITEM(v, 7,
8468 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
8469 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8470 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008471#endif
8472
Victor Stinner8c62be82010-05-06 00:08:46 +00008473 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008474}
8475
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008476PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008477"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008478Perform an fstatvfs system call on the given fd.\n\
8479Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008480
8481static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008482posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008483{
Victor Stinner8c62be82010-05-06 00:08:46 +00008484 int fd, res;
8485 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008486
Victor Stinner8c62be82010-05-06 00:08:46 +00008487 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
8488 return NULL;
8489 Py_BEGIN_ALLOW_THREADS
8490 res = fstatvfs(fd, &st);
8491 Py_END_ALLOW_THREADS
8492 if (res != 0)
8493 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008494
Victor Stinner8c62be82010-05-06 00:08:46 +00008495 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008496}
Thomas Wouters477c8d52006-05-27 19:21:47 +00008497#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008498
8499
Thomas Wouters477c8d52006-05-27 19:21:47 +00008500#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008501#include <sys/statvfs.h>
8502
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008503PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008504"statvfs(path)\n\n\
8505Perform a statvfs system call on the given path.\n\
8506\n\
8507path may always be specified as a string.\n\
8508On some platforms, path may also be specified as an open file descriptor.\n\
8509 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008510
8511static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008512posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008513{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008514 static char *keywords[] = {"path", NULL};
8515 path_t path;
8516 int result;
8517 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008518 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008519
Larry Hastings9cf065c2012-06-22 16:30:09 -07008520 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008521 path.function_name = "statvfs";
Larry Hastings9cf065c2012-06-22 16:30:09 -07008522#ifdef HAVE_FSTATVFS
8523 path.allow_fd = 1;
8524#endif
8525 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
8526 path_converter, &path
8527 ))
8528 return NULL;
8529
8530 Py_BEGIN_ALLOW_THREADS
8531#ifdef HAVE_FSTATVFS
8532 if (path.fd != -1) {
8533#ifdef __APPLE__
8534 /* handle weak-linking on Mac OS X 10.3 */
8535 if (fstatvfs == NULL) {
8536 fd_specified("statvfs", path.fd);
8537 goto exit;
8538 }
8539#endif
8540 result = fstatvfs(path.fd, &st);
8541 }
8542 else
8543#endif
8544 result = statvfs(path.narrow, &st);
8545 Py_END_ALLOW_THREADS
8546
8547 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01008548 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008549 goto exit;
8550 }
8551
8552 return_value = _pystatvfs_fromstructstatvfs(st);
8553
8554exit:
8555 path_cleanup(&path);
8556 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00008557}
8558#endif /* HAVE_STATVFS */
8559
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008560#ifdef MS_WINDOWS
8561PyDoc_STRVAR(win32__getdiskusage__doc__,
8562"_getdiskusage(path) -> (total, free)\n\n\
8563Return disk usage statistics about the given path as (total, free) tuple.");
8564
8565static PyObject *
8566win32__getdiskusage(PyObject *self, PyObject *args)
8567{
8568 BOOL retval;
8569 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01008570 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008571
Victor Stinner6139c1b2011-11-09 22:14:14 +01008572 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008573 return NULL;
8574
8575 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01008576 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008577 Py_END_ALLOW_THREADS
8578 if (retval == 0)
8579 return PyErr_SetFromWindowsErr(0);
8580
8581 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
8582}
8583#endif
8584
8585
Fred Drakec9680921999-12-13 16:37:25 +00008586/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
8587 * It maps strings representing configuration variable names to
8588 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00008589 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00008590 * rarely-used constants. There are three separate tables that use
8591 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00008592 *
8593 * This code is always included, even if none of the interfaces that
8594 * need it are included. The #if hackery needed to avoid it would be
8595 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00008596 */
8597struct constdef {
8598 char *name;
8599 long value;
8600};
8601
Fred Drake12c6e2d1999-12-14 21:25:03 +00008602static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008603conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00008604 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00008605{
Christian Heimes217cfd12007-12-02 14:31:20 +00008606 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008607 *valuep = PyLong_AS_LONG(arg);
8608 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00008609 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00008610 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00008611 /* look up the value in the table using a binary search */
8612 size_t lo = 0;
8613 size_t mid;
8614 size_t hi = tablesize;
8615 int cmp;
8616 const char *confname;
8617 if (!PyUnicode_Check(arg)) {
8618 PyErr_SetString(PyExc_TypeError,
8619 "configuration names must be strings or integers");
8620 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008621 }
Stefan Krah0e803b32010-11-26 16:16:47 +00008622 confname = _PyUnicode_AsString(arg);
8623 if (confname == NULL)
8624 return 0;
8625 while (lo < hi) {
8626 mid = (lo + hi) / 2;
8627 cmp = strcmp(confname, table[mid].name);
8628 if (cmp < 0)
8629 hi = mid;
8630 else if (cmp > 0)
8631 lo = mid + 1;
8632 else {
8633 *valuep = table[mid].value;
8634 return 1;
8635 }
8636 }
8637 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
8638 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008639 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00008640}
8641
8642
8643#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
8644static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008645#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008646 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008647#endif
8648#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008649 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008650#endif
Fred Drakec9680921999-12-13 16:37:25 +00008651#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008652 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008653#endif
8654#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00008655 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00008656#endif
8657#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00008658 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00008659#endif
8660#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00008661 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00008662#endif
8663#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008664 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008665#endif
8666#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00008667 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00008668#endif
8669#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008670 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00008671#endif
8672#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008673 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008674#endif
8675#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008676 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00008677#endif
8678#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008679 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008680#endif
8681#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008682 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00008683#endif
8684#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008685 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008686#endif
8687#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008688 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00008689#endif
8690#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008691 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008692#endif
8693#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008694 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00008695#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00008696#ifdef _PC_ACL_ENABLED
8697 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
8698#endif
8699#ifdef _PC_MIN_HOLE_SIZE
8700 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
8701#endif
8702#ifdef _PC_ALLOC_SIZE_MIN
8703 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
8704#endif
8705#ifdef _PC_REC_INCR_XFER_SIZE
8706 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
8707#endif
8708#ifdef _PC_REC_MAX_XFER_SIZE
8709 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
8710#endif
8711#ifdef _PC_REC_MIN_XFER_SIZE
8712 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
8713#endif
8714#ifdef _PC_REC_XFER_ALIGN
8715 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
8716#endif
8717#ifdef _PC_SYMLINK_MAX
8718 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
8719#endif
8720#ifdef _PC_XATTR_ENABLED
8721 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
8722#endif
8723#ifdef _PC_XATTR_EXISTS
8724 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
8725#endif
8726#ifdef _PC_TIMESTAMP_RESOLUTION
8727 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
8728#endif
Fred Drakec9680921999-12-13 16:37:25 +00008729};
8730
Fred Drakec9680921999-12-13 16:37:25 +00008731static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008732conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008733{
8734 return conv_confname(arg, valuep, posix_constants_pathconf,
8735 sizeof(posix_constants_pathconf)
8736 / sizeof(struct constdef));
8737}
8738#endif
8739
8740#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008741PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008742"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008743Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008744If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00008745
8746static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008747posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008748{
8749 PyObject *result = NULL;
8750 int name, fd;
8751
Fred Drake12c6e2d1999-12-14 21:25:03 +00008752 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
8753 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008754 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008755
Stefan Krah0e803b32010-11-26 16:16:47 +00008756 errno = 0;
8757 limit = fpathconf(fd, name);
8758 if (limit == -1 && errno != 0)
8759 posix_error();
8760 else
8761 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008762 }
8763 return result;
8764}
8765#endif
8766
8767
8768#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008769PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008770"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008771Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008772If there is no limit, return -1.\n\
8773On some platforms, path may also be specified as an open file descriptor.\n\
8774 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00008775
8776static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008777posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00008778{
Georg Brandl306336b2012-06-24 12:55:33 +02008779 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00008780 PyObject *result = NULL;
8781 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02008782 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00008783
Georg Brandl306336b2012-06-24 12:55:33 +02008784 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008785 path.function_name = "pathconf";
Georg Brandl306336b2012-06-24 12:55:33 +02008786#ifdef HAVE_FPATHCONF
8787 path.allow_fd = 1;
8788#endif
8789 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
8790 path_converter, &path,
8791 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008792 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008793
Victor Stinner8c62be82010-05-06 00:08:46 +00008794 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02008795#ifdef HAVE_FPATHCONF
8796 if (path.fd != -1)
8797 limit = fpathconf(path.fd, name);
8798 else
8799#endif
8800 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00008801 if (limit == -1 && errno != 0) {
8802 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00008803 /* could be a path or name problem */
8804 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00008805 else
Victor Stinner292c8352012-10-30 02:17:38 +01008806 result = path_error(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00008807 }
8808 else
8809 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008810 }
Georg Brandl306336b2012-06-24 12:55:33 +02008811 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00008812 return result;
8813}
8814#endif
8815
8816#ifdef HAVE_CONFSTR
8817static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008818#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00008819 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00008820#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00008821#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008822 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008823#endif
8824#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008825 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008826#endif
Fred Draked86ed291999-12-15 15:34:33 +00008827#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008828 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008829#endif
8830#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008831 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008832#endif
8833#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008834 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008835#endif
8836#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008837 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008838#endif
Fred Drakec9680921999-12-13 16:37:25 +00008839#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008840 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008841#endif
8842#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008843 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008844#endif
8845#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008846 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008847#endif
8848#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008849 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008850#endif
8851#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008852 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008853#endif
8854#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008855 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008856#endif
8857#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008858 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008859#endif
8860#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008861 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008862#endif
Fred Draked86ed291999-12-15 15:34:33 +00008863#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00008864 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00008865#endif
Fred Drakec9680921999-12-13 16:37:25 +00008866#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00008867 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00008868#endif
Fred Draked86ed291999-12-15 15:34:33 +00008869#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008870 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00008871#endif
8872#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008873 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00008874#endif
8875#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008876 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008877#endif
8878#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008879 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00008880#endif
Fred Drakec9680921999-12-13 16:37:25 +00008881#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008882 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008883#endif
8884#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008885 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008886#endif
8887#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008888 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008889#endif
8890#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008891 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008892#endif
8893#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008894 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008895#endif
8896#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008897 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008898#endif
8899#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008900 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008901#endif
8902#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008903 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008904#endif
8905#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008906 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008907#endif
8908#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008909 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008910#endif
8911#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008912 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008913#endif
8914#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008915 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008916#endif
8917#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008918 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008919#endif
8920#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008921 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008922#endif
8923#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008924 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008925#endif
8926#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008927 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008928#endif
Fred Draked86ed291999-12-15 15:34:33 +00008929#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008930 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008931#endif
8932#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008933 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00008934#endif
8935#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00008936 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00008937#endif
8938#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008939 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008940#endif
8941#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008942 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008943#endif
8944#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00008945 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00008946#endif
8947#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008948 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00008949#endif
8950#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00008951 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00008952#endif
8953#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008954 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008955#endif
8956#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008957 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008958#endif
8959#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008960 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008961#endif
8962#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008963 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008964#endif
8965#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00008966 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00008967#endif
Fred Drakec9680921999-12-13 16:37:25 +00008968};
8969
8970static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008971conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008972{
8973 return conv_confname(arg, valuep, posix_constants_confstr,
8974 sizeof(posix_constants_confstr)
8975 / sizeof(struct constdef));
8976}
8977
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008978PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008979"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008980Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008981
8982static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008983posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008984{
8985 PyObject *result = NULL;
8986 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00008987 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00008988 int len;
Fred Drakec9680921999-12-13 16:37:25 +00008989
Victor Stinnercb043522010-09-10 23:49:04 +00008990 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
8991 return NULL;
8992
8993 errno = 0;
8994 len = confstr(name, buffer, sizeof(buffer));
8995 if (len == 0) {
8996 if (errno) {
8997 posix_error();
8998 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00008999 }
9000 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009001 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009002 }
9003 }
Victor Stinnercb043522010-09-10 23:49:04 +00009004
9005 if ((unsigned int)len >= sizeof(buffer)) {
9006 char *buf = PyMem_Malloc(len);
9007 if (buf == NULL)
9008 return PyErr_NoMemory();
9009 confstr(name, buf, len);
9010 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9011 PyMem_Free(buf);
9012 }
9013 else
9014 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009015 return result;
9016}
9017#endif
9018
9019
9020#ifdef HAVE_SYSCONF
9021static struct constdef posix_constants_sysconf[] = {
9022#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009023 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009024#endif
9025#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009026 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009027#endif
9028#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009029 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009030#endif
9031#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009032 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009033#endif
9034#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009035 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009036#endif
9037#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009038 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009039#endif
9040#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009041 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009042#endif
9043#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009044 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009045#endif
9046#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009047 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009048#endif
9049#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009050 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009051#endif
Fred Draked86ed291999-12-15 15:34:33 +00009052#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009053 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009054#endif
9055#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009056 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009057#endif
Fred Drakec9680921999-12-13 16:37:25 +00009058#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009059 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009060#endif
Fred Drakec9680921999-12-13 16:37:25 +00009061#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009062 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009063#endif
9064#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009065 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009066#endif
9067#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009068 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009069#endif
9070#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009071 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009072#endif
9073#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009074 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009075#endif
Fred Draked86ed291999-12-15 15:34:33 +00009076#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009077 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009078#endif
Fred Drakec9680921999-12-13 16:37:25 +00009079#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009080 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009081#endif
9082#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009083 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009084#endif
9085#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009086 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009087#endif
9088#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009089 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009090#endif
9091#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009092 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009093#endif
Fred Draked86ed291999-12-15 15:34:33 +00009094#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009095 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009096#endif
Fred Drakec9680921999-12-13 16:37:25 +00009097#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009098 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009099#endif
9100#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009101 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009102#endif
9103#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009104 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009105#endif
9106#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009107 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009108#endif
9109#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009110 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009111#endif
9112#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009113 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009114#endif
9115#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009116 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009117#endif
9118#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009119 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009120#endif
9121#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009122 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009123#endif
9124#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009125 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009126#endif
9127#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009128 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009129#endif
9130#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009131 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009132#endif
9133#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009134 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009135#endif
9136#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009137 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009138#endif
9139#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009140 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009141#endif
9142#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009143 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009144#endif
9145#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009146 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009147#endif
9148#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009149 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009150#endif
9151#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009152 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009153#endif
9154#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009155 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009156#endif
9157#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009158 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009159#endif
9160#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009161 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009162#endif
9163#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009164 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009165#endif
Fred Draked86ed291999-12-15 15:34:33 +00009166#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009167 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009168#endif
Fred Drakec9680921999-12-13 16:37:25 +00009169#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009170 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009171#endif
9172#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009173 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009174#endif
9175#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009176 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009177#endif
Fred Draked86ed291999-12-15 15:34:33 +00009178#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009179 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009180#endif
Fred Drakec9680921999-12-13 16:37:25 +00009181#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009182 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009183#endif
Fred Draked86ed291999-12-15 15:34:33 +00009184#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009185 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009186#endif
9187#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009188 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009189#endif
Fred Drakec9680921999-12-13 16:37:25 +00009190#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009191 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009192#endif
9193#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009194 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009195#endif
9196#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009197 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009198#endif
9199#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009200 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009201#endif
Fred Draked86ed291999-12-15 15:34:33 +00009202#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009203 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009204#endif
Fred Drakec9680921999-12-13 16:37:25 +00009205#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009206 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009207#endif
9208#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009209 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009210#endif
9211#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009212 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009213#endif
9214#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009215 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009216#endif
9217#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009218 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009219#endif
9220#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009221 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009222#endif
9223#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009224 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009225#endif
Fred Draked86ed291999-12-15 15:34:33 +00009226#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009227 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009228#endif
Fred Drakec9680921999-12-13 16:37:25 +00009229#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009230 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009231#endif
9232#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009233 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009234#endif
Fred Draked86ed291999-12-15 15:34:33 +00009235#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009236 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009237#endif
Fred Drakec9680921999-12-13 16:37:25 +00009238#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009239 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009240#endif
9241#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009242 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009243#endif
9244#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009245 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009246#endif
9247#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009248 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009249#endif
9250#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009251 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009252#endif
9253#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009254 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009255#endif
9256#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009257 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009258#endif
9259#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009260 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009261#endif
9262#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009263 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009264#endif
Fred Draked86ed291999-12-15 15:34:33 +00009265#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009266 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009267#endif
9268#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009269 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009270#endif
Fred Drakec9680921999-12-13 16:37:25 +00009271#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009272 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009273#endif
9274#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009275 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009276#endif
9277#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009278 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009279#endif
9280#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009281 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009282#endif
9283#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009284 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009285#endif
9286#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009287 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009288#endif
9289#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009290 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009291#endif
9292#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009293 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009294#endif
9295#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009296 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009297#endif
9298#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009299 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009300#endif
9301#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00009302 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00009303#endif
9304#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009305 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00009306#endif
9307#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009308 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00009309#endif
9310#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00009311 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00009312#endif
9313#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00009314 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00009315#endif
9316#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00009317 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00009318#endif
9319#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00009320 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00009321#endif
9322#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009323 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009324#endif
9325#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009326 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009327#endif
9328#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00009329 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00009330#endif
9331#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009332 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009333#endif
9334#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009335 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009336#endif
9337#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00009338 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00009339#endif
9340#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009341 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009342#endif
9343#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009344 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009345#endif
9346#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009347 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00009348#endif
9349#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00009350 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00009351#endif
9352#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009353 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009354#endif
9355#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009356 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009357#endif
9358#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009359 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00009360#endif
9361#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009362 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009363#endif
9364#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009365 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009366#endif
9367#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009368 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009369#endif
9370#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009371 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009372#endif
9373#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009374 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009375#endif
Fred Draked86ed291999-12-15 15:34:33 +00009376#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00009377 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00009378#endif
Fred Drakec9680921999-12-13 16:37:25 +00009379#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00009380 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00009381#endif
9382#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009383 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009384#endif
9385#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00009386 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00009387#endif
9388#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009389 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009390#endif
9391#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009392 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009393#endif
9394#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009395 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009396#endif
9397#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00009398 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00009399#endif
9400#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009401 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009402#endif
9403#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009404 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009405#endif
9406#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009407 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009408#endif
9409#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009410 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009411#endif
9412#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009413 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00009414#endif
9415#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009416 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00009417#endif
9418#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00009419 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00009420#endif
9421#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009422 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009423#endif
9424#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009425 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009426#endif
9427#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009428 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009429#endif
9430#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009431 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00009432#endif
9433#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009434 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009435#endif
9436#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009437 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009438#endif
9439#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009440 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009441#endif
9442#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009443 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009444#endif
9445#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009446 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009447#endif
9448#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009449 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009450#endif
9451#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00009452 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00009453#endif
9454#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009455 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009456#endif
9457#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009458 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009459#endif
9460#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009461 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009462#endif
9463#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009464 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009465#endif
9466#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00009467 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00009468#endif
9469#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009470 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009471#endif
9472#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00009473 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00009474#endif
9475#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009476 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009477#endif
9478#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00009479 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00009480#endif
9481#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00009482 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00009483#endif
9484#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00009485 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00009486#endif
9487#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00009488 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00009489#endif
9490#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009491 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009492#endif
9493#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00009494 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00009495#endif
9496#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00009497 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00009498#endif
9499#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009500 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009501#endif
9502#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009503 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009504#endif
9505#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00009506 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00009507#endif
9508#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00009509 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00009510#endif
9511#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00009512 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00009513#endif
9514};
9515
9516static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009517conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009518{
9519 return conv_confname(arg, valuep, posix_constants_sysconf,
9520 sizeof(posix_constants_sysconf)
9521 / sizeof(struct constdef));
9522}
9523
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009524PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009525"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009526Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009527
9528static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009529posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009530{
9531 PyObject *result = NULL;
9532 int name;
9533
9534 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
9535 int value;
9536
9537 errno = 0;
9538 value = sysconf(name);
9539 if (value == -1 && errno != 0)
9540 posix_error();
9541 else
Christian Heimes217cfd12007-12-02 14:31:20 +00009542 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00009543 }
9544 return result;
9545}
9546#endif
9547
9548
Fred Drakebec628d1999-12-15 18:31:10 +00009549/* This code is used to ensure that the tables of configuration value names
9550 * are in sorted order as required by conv_confname(), and also to build the
9551 * the exported dictionaries that are used to publish information about the
9552 * names available on the host platform.
9553 *
9554 * Sorting the table at runtime ensures that the table is properly ordered
9555 * when used, even for platforms we're not able to test on. It also makes
9556 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00009557 */
Fred Drakebec628d1999-12-15 18:31:10 +00009558
9559static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009560cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00009561{
9562 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009563 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00009564 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009565 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00009566
9567 return strcmp(c1->name, c2->name);
9568}
9569
9570static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009571setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00009572 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009573{
Fred Drakebec628d1999-12-15 18:31:10 +00009574 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00009575 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00009576
9577 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
9578 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00009579 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00009580 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009581
Barry Warsaw3155db32000-04-13 15:20:40 +00009582 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009583 PyObject *o = PyLong_FromLong(table[i].value);
9584 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
9585 Py_XDECREF(o);
9586 Py_DECREF(d);
9587 return -1;
9588 }
9589 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00009590 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00009591 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00009592}
9593
Fred Drakebec628d1999-12-15 18:31:10 +00009594/* Return -1 on failure, 0 on success. */
9595static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00009596setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009597{
9598#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00009599 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00009600 sizeof(posix_constants_pathconf)
9601 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009602 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009603 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009604#endif
9605#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00009606 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00009607 sizeof(posix_constants_confstr)
9608 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009609 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009610 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009611#endif
9612#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00009613 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00009614 sizeof(posix_constants_sysconf)
9615 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009616 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009617 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009618#endif
Fred Drakebec628d1999-12-15 18:31:10 +00009619 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00009620}
Fred Draked86ed291999-12-15 15:34:33 +00009621
9622
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009623PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009624"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009625Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009626in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009627
9628static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009629posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009630{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009631 abort();
9632 /*NOTREACHED*/
9633 Py_FatalError("abort() called from Python code didn't abort!");
9634 return NULL;
9635}
Fred Drakebec628d1999-12-15 18:31:10 +00009636
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00009637#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009638PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00009639"startfile(filepath [, operation]) - Start a file with its associated\n\
9640application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009641\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00009642When \"operation\" is not specified or \"open\", this acts like\n\
9643double-clicking the file in Explorer, or giving the file name as an\n\
9644argument to the DOS \"start\" command: the file is opened with whatever\n\
9645application (if any) its extension is associated.\n\
9646When another \"operation\" is given, it specifies what should be done with\n\
9647the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009648\n\
9649startfile returns as soon as the associated application is launched.\n\
9650There is no option to wait for the application to close, and no way\n\
9651to retrieve the application's exit status.\n\
9652\n\
9653The filepath is relative to the current directory. If you want to use\n\
9654an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009655the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00009656
9657static PyObject *
9658win32_startfile(PyObject *self, PyObject *args)
9659{
Victor Stinner8c62be82010-05-06 00:08:46 +00009660 PyObject *ofilepath;
9661 char *filepath;
9662 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02009663 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +00009664 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00009665
Victor Stinnereb5657a2011-09-30 01:44:27 +02009666 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009667 if (!PyArg_ParseTuple(args, "U|s:startfile",
9668 &unipath, &operation)) {
9669 PyErr_Clear();
9670 goto normal;
9671 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009672
Victor Stinner8c62be82010-05-06 00:08:46 +00009673 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009674 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +00009675 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +02009676 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009677 PyErr_Clear();
9678 operation = NULL;
9679 goto normal;
9680 }
9681 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009682
Victor Stinnereb5657a2011-09-30 01:44:27 +02009683 wpath = PyUnicode_AsUnicode(unipath);
9684 if (wpath == NULL)
9685 goto normal;
9686 if (uoperation) {
9687 woperation = PyUnicode_AsUnicode(uoperation);
9688 if (woperation == NULL)
9689 goto normal;
9690 }
9691 else
9692 woperation = NULL;
9693
Victor Stinner8c62be82010-05-06 00:08:46 +00009694 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02009695 rc = ShellExecuteW((HWND)0, woperation, wpath,
9696 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +00009697 Py_END_ALLOW_THREADS
9698
Victor Stinnereb5657a2011-09-30 01:44:27 +02009699 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +00009700 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009701 win32_error_object("startfile", unipath);
9702 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009703 }
9704 Py_INCREF(Py_None);
9705 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009706
9707normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00009708 if (!PyArg_ParseTuple(args, "O&|s:startfile",
9709 PyUnicode_FSConverter, &ofilepath,
9710 &operation))
9711 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01009712 if (win32_warn_bytes_api()) {
9713 Py_DECREF(ofilepath);
9714 return NULL;
9715 }
Victor Stinner8c62be82010-05-06 00:08:46 +00009716 filepath = PyBytes_AsString(ofilepath);
9717 Py_BEGIN_ALLOW_THREADS
9718 rc = ShellExecute((HWND)0, operation, filepath,
9719 NULL, NULL, SW_SHOWNORMAL);
9720 Py_END_ALLOW_THREADS
9721 if (rc <= (HINSTANCE)32) {
9722 PyObject *errval = win32_error("startfile", filepath);
9723 Py_DECREF(ofilepath);
9724 return errval;
9725 }
9726 Py_DECREF(ofilepath);
9727 Py_INCREF(Py_None);
9728 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00009729}
9730#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009731
Martin v. Löwis438b5342002-12-27 10:16:42 +00009732#ifdef HAVE_GETLOADAVG
9733PyDoc_STRVAR(posix_getloadavg__doc__,
9734"getloadavg() -> (float, float, float)\n\n\
9735Return the number of processes in the system run queue averaged over\n\
9736the last 1, 5, and 15 minutes or raises OSError if the load average\n\
9737was unobtainable");
9738
9739static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009740posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00009741{
9742 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00009743 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009744 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
9745 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00009746 } else
Stefan Krah0e803b32010-11-26 16:16:47 +00009747 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00009748}
9749#endif
9750
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009751PyDoc_STRVAR(device_encoding__doc__,
9752"device_encoding(fd) -> str\n\n\
9753Return a string describing the encoding of the device\n\
9754if the output is a terminal; else return None.");
9755
9756static PyObject *
9757device_encoding(PyObject *self, PyObject *args)
9758{
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -05009760
Victor Stinner8c62be82010-05-06 00:08:46 +00009761 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
9762 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -05009763
9764 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009765}
9766
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009767#ifdef HAVE_SETRESUID
9768PyDoc_STRVAR(posix_setresuid__doc__,
9769"setresuid(ruid, euid, suid)\n\n\
9770Set the current process's real, effective, and saved user ids.");
9771
9772static PyObject*
9773posix_setresuid (PyObject *self, PyObject *args)
9774{
Victor Stinner8c62be82010-05-06 00:08:46 +00009775 /* We assume uid_t is no larger than a long. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02009776 uid_t ruid, euid, suid;
9777 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
9778 _Py_Uid_Converter, &ruid,
9779 _Py_Uid_Converter, &euid,
9780 _Py_Uid_Converter, &suid))
Victor Stinner8c62be82010-05-06 00:08:46 +00009781 return NULL;
9782 if (setresuid(ruid, euid, suid) < 0)
9783 return posix_error();
9784 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009785}
9786#endif
9787
9788#ifdef HAVE_SETRESGID
9789PyDoc_STRVAR(posix_setresgid__doc__,
9790"setresgid(rgid, egid, sgid)\n\n\
9791Set the current process's real, effective, and saved group ids.");
9792
9793static PyObject*
9794posix_setresgid (PyObject *self, PyObject *args)
9795{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02009796 gid_t rgid, egid, sgid;
9797 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
9798 _Py_Gid_Converter, &rgid,
9799 _Py_Gid_Converter, &egid,
9800 _Py_Gid_Converter, &sgid))
Victor Stinner8c62be82010-05-06 00:08:46 +00009801 return NULL;
9802 if (setresgid(rgid, egid, sgid) < 0)
9803 return posix_error();
9804 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009805}
9806#endif
9807
9808#ifdef HAVE_GETRESUID
9809PyDoc_STRVAR(posix_getresuid__doc__,
9810"getresuid() -> (ruid, euid, suid)\n\n\
9811Get tuple of the current process's real, effective, and saved user ids.");
9812
9813static PyObject*
9814posix_getresuid (PyObject *self, PyObject *noargs)
9815{
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +00009817 if (getresuid(&ruid, &euid, &suid) < 0)
9818 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02009819 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
9820 _PyLong_FromUid(euid),
9821 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009822}
9823#endif
9824
9825#ifdef HAVE_GETRESGID
9826PyDoc_STRVAR(posix_getresgid__doc__,
9827"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00009828Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009829
9830static PyObject*
9831posix_getresgid (PyObject *self, PyObject *noargs)
9832{
Victor Stinner8c62be82010-05-06 00:08:46 +00009833 uid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 if (getresgid(&rgid, &egid, &sgid) < 0)
9835 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02009836 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
9837 _PyLong_FromGid(egid),
9838 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009839}
9840#endif
9841
Benjamin Peterson9428d532011-09-14 11:45:52 -04009842#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -04009843
Benjamin Peterson799bd802011-08-31 22:15:17 -04009844PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009845"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
9846Return the value of extended attribute attribute on path.\n\
9847\n\
9848path may be either a string or an open file descriptor.\n\
9849If follow_symlinks is False, and the last element of the path is a symbolic\n\
9850 link, getxattr will examine the symbolic link itself instead of the file\n\
9851 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -04009852
9853static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009854posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04009855{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009856 path_t path;
9857 path_t attribute;
9858 int follow_symlinks = 1;
9859 PyObject *buffer = NULL;
9860 int i;
9861 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -04009862
Larry Hastings9cf065c2012-06-22 16:30:09 -07009863 memset(&path, 0, sizeof(path));
9864 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +01009865 path.function_name = "getxattr";
9866 attribute.function_name = "getxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009867 path.allow_fd = 1;
9868 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
9869 path_converter, &path,
9870 path_converter, &attribute,
9871 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -04009872 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009873
Larry Hastings9cf065c2012-06-22 16:30:09 -07009874 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
9875 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009876
Larry Hastings9cf065c2012-06-22 16:30:09 -07009877 for (i = 0; ; i++) {
9878 void *ptr;
9879 ssize_t result;
9880 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
9881 Py_ssize_t buffer_size = buffer_sizes[i];
9882 if (!buffer_size) {
Victor Stinner292c8352012-10-30 02:17:38 +01009883 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009884 goto exit;
9885 }
9886 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
9887 if (!buffer)
9888 goto exit;
9889 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009890
Larry Hastings9cf065c2012-06-22 16:30:09 -07009891 Py_BEGIN_ALLOW_THREADS;
9892 if (path.fd >= 0)
9893 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
9894 else if (follow_symlinks)
9895 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
9896 else
9897 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
9898 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009899
Larry Hastings9cf065c2012-06-22 16:30:09 -07009900 if (result < 0) {
9901 Py_DECREF(buffer);
9902 buffer = NULL;
9903 if (errno == ERANGE)
9904 continue;
Victor Stinner292c8352012-10-30 02:17:38 +01009905 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009906 goto exit;
9907 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009908
Larry Hastings9cf065c2012-06-22 16:30:09 -07009909 if (result != buffer_size) {
9910 /* Can only shrink. */
9911 _PyBytes_Resize(&buffer, result);
9912 }
9913 break;
9914 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009915
Larry Hastings9cf065c2012-06-22 16:30:09 -07009916exit:
9917 path_cleanup(&path);
9918 path_cleanup(&attribute);
9919 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009920}
9921
9922PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009923"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
9924Set extended attribute attribute on path to value.\n\
9925path may be either a string or an open file descriptor.\n\
9926If follow_symlinks is False, and the last element of the path is a symbolic\n\
9927 link, setxattr will modify the symbolic link itself instead of the file\n\
9928 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -04009929
9930static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009931posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04009932{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009933 path_t path;
9934 path_t attribute;
9935 Py_buffer value;
9936 int flags = 0;
9937 int follow_symlinks = 1;
9938 int result;
9939 PyObject *return_value = NULL;
9940 static char *keywords[] = {"path", "attribute", "value",
9941 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -04009942
Larry Hastings9cf065c2012-06-22 16:30:09 -07009943 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009944 path.function_name = "setxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009945 path.allow_fd = 1;
9946 memset(&attribute, 0, sizeof(attribute));
9947 memset(&value, 0, sizeof(value));
9948 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
9949 keywords,
9950 path_converter, &path,
9951 path_converter, &attribute,
9952 &value, &flags,
9953 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -04009954 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009955
9956 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
9957 goto exit;
9958
Benjamin Peterson799bd802011-08-31 22:15:17 -04009959 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009960 if (path.fd > -1)
9961 result = fsetxattr(path.fd, attribute.narrow,
9962 value.buf, value.len, flags);
9963 else if (follow_symlinks)
9964 result = setxattr(path.narrow, attribute.narrow,
9965 value.buf, value.len, flags);
9966 else
9967 result = lsetxattr(path.narrow, attribute.narrow,
9968 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009969 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009970
Larry Hastings9cf065c2012-06-22 16:30:09 -07009971 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01009972 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009973 goto exit;
9974 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009975
Larry Hastings9cf065c2012-06-22 16:30:09 -07009976 return_value = Py_None;
9977 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009978
Larry Hastings9cf065c2012-06-22 16:30:09 -07009979exit:
9980 path_cleanup(&path);
9981 path_cleanup(&attribute);
9982 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009983
Larry Hastings9cf065c2012-06-22 16:30:09 -07009984 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009985}
9986
9987PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009988"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
9989Remove extended attribute attribute on path.\n\
9990path may be either a string or an open file descriptor.\n\
9991If follow_symlinks is False, and the last element of the path is a symbolic\n\
9992 link, removexattr will modify the symbolic link itself instead of the file\n\
9993 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -04009994
9995static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009996posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04009997{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009998 path_t path;
9999 path_t attribute;
10000 int follow_symlinks = 1;
10001 int result;
10002 PyObject *return_value = NULL;
10003 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010004
Larry Hastings9cf065c2012-06-22 16:30:09 -070010005 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010006 path.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010007 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010008 attribute.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010009 path.allow_fd = 1;
10010 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10011 keywords,
10012 path_converter, &path,
10013 path_converter, &attribute,
10014 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010015 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010016
10017 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10018 goto exit;
10019
Benjamin Peterson799bd802011-08-31 22:15:17 -040010020 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010021 if (path.fd > -1)
10022 result = fremovexattr(path.fd, attribute.narrow);
10023 else if (follow_symlinks)
10024 result = removexattr(path.narrow, attribute.narrow);
10025 else
10026 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010027 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010028
Larry Hastings9cf065c2012-06-22 16:30:09 -070010029 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010030 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010031 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010032 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010033
Larry Hastings9cf065c2012-06-22 16:30:09 -070010034 return_value = Py_None;
10035 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010036
Larry Hastings9cf065c2012-06-22 16:30:09 -070010037exit:
10038 path_cleanup(&path);
10039 path_cleanup(&attribute);
10040
10041 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010042}
10043
10044PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010045"listxattr(path='.', *, follow_symlinks=True)\n\n\
10046Return a list of extended attributes on path.\n\
10047\n\
10048path may be either None, a string, or an open file descriptor.\n\
10049if path is None, listxattr will examine the current directory.\n\
10050If follow_symlinks is False, and the last element of the path is a symbolic\n\
10051 link, listxattr will examine the symbolic link itself instead of the file\n\
10052 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010053
10054static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010055posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010056{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010057 path_t path;
10058 int follow_symlinks = 1;
10059 Py_ssize_t i;
10060 PyObject *result = NULL;
10061 char *buffer = NULL;
10062 char *name;
10063 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010064
Larry Hastings9cf065c2012-06-22 16:30:09 -070010065 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010066 path.function_name = "listxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010067 path.allow_fd = 1;
10068 path.fd = -1;
10069 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10070 path_converter, &path,
10071 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010072 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010073
Larry Hastings9cf065c2012-06-22 16:30:09 -070010074 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10075 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010076
Larry Hastings9cf065c2012-06-22 16:30:09 -070010077 name = path.narrow ? path.narrow : ".";
10078 for (i = 0; ; i++) {
10079 char *start, *trace, *end;
10080 ssize_t length;
10081 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10082 Py_ssize_t buffer_size = buffer_sizes[i];
10083 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010084 /* ERANGE */
Victor Stinner292c8352012-10-30 02:17:38 +010010085 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010086 break;
10087 }
10088 buffer = PyMem_MALLOC(buffer_size);
10089 if (!buffer) {
10090 PyErr_NoMemory();
10091 break;
10092 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010093
Larry Hastings9cf065c2012-06-22 16:30:09 -070010094 Py_BEGIN_ALLOW_THREADS;
10095 if (path.fd > -1)
10096 length = flistxattr(path.fd, buffer, buffer_size);
10097 else if (follow_symlinks)
10098 length = listxattr(name, buffer, buffer_size);
10099 else
10100 length = llistxattr(name, buffer, buffer_size);
10101 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010102
Larry Hastings9cf065c2012-06-22 16:30:09 -070010103 if (length < 0) {
10104 if (errno == ERANGE)
10105 continue;
Victor Stinner292c8352012-10-30 02:17:38 +010010106 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010107 break;
10108 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010109
Larry Hastings9cf065c2012-06-22 16:30:09 -070010110 result = PyList_New(0);
10111 if (!result) {
10112 goto exit;
10113 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010114
Larry Hastings9cf065c2012-06-22 16:30:09 -070010115 end = buffer + length;
10116 for (trace = start = buffer; trace != end; trace++) {
10117 if (!*trace) {
10118 int error;
10119 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10120 trace - start);
10121 if (!attribute) {
10122 Py_DECREF(result);
10123 result = NULL;
10124 goto exit;
10125 }
10126 error = PyList_Append(result, attribute);
10127 Py_DECREF(attribute);
10128 if (error) {
10129 Py_DECREF(result);
10130 result = NULL;
10131 goto exit;
10132 }
10133 start = trace + 1;
10134 }
10135 }
10136 break;
10137 }
10138exit:
10139 path_cleanup(&path);
10140 if (buffer)
10141 PyMem_FREE(buffer);
10142 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010143}
10144
Benjamin Peterson9428d532011-09-14 11:45:52 -040010145#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010146
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010147
Georg Brandl2fb477c2012-02-21 00:33:36 +010010148PyDoc_STRVAR(posix_urandom__doc__,
10149"urandom(n) -> str\n\n\
10150Return n random bytes suitable for cryptographic use.");
10151
10152static PyObject *
10153posix_urandom(PyObject *self, PyObject *args)
10154{
10155 Py_ssize_t size;
10156 PyObject *result;
10157 int ret;
10158
10159 /* Read arguments */
10160 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10161 return NULL;
10162 if (size < 0)
10163 return PyErr_Format(PyExc_ValueError,
10164 "negative argument not allowed");
10165 result = PyBytes_FromStringAndSize(NULL, size);
10166 if (result == NULL)
10167 return NULL;
10168
10169 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10170 PyBytes_GET_SIZE(result));
10171 if (ret == -1) {
10172 Py_DECREF(result);
10173 return NULL;
10174 }
10175 return result;
10176}
10177
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010178/* Terminal size querying */
10179
10180static PyTypeObject TerminalSizeType;
10181
10182PyDoc_STRVAR(TerminalSize_docstring,
10183 "A tuple of (columns, lines) for holding terminal window size");
10184
10185static PyStructSequence_Field TerminalSize_fields[] = {
10186 {"columns", "width of the terminal window in characters"},
10187 {"lines", "height of the terminal window in characters"},
10188 {NULL, NULL}
10189};
10190
10191static PyStructSequence_Desc TerminalSize_desc = {
10192 "os.terminal_size",
10193 TerminalSize_docstring,
10194 TerminalSize_fields,
10195 2,
10196};
10197
10198#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10199PyDoc_STRVAR(termsize__doc__,
10200 "Return the size of the terminal window as (columns, lines).\n" \
10201 "\n" \
10202 "The optional argument fd (default standard output) specifies\n" \
10203 "which file descriptor should be queried.\n" \
10204 "\n" \
10205 "If the file descriptor is not connected to a terminal, an OSError\n" \
10206 "is thrown.\n" \
10207 "\n" \
10208 "This function will only be defined if an implementation is\n" \
10209 "available for this system.\n" \
10210 "\n" \
10211 "shutil.get_terminal_size is the high-level function which should \n" \
10212 "normally be used, os.get_terminal_size is the low-level implementation.");
10213
10214static PyObject*
10215get_terminal_size(PyObject *self, PyObject *args)
10216{
10217 int columns, lines;
10218 PyObject *termsize;
10219
10220 int fd = fileno(stdout);
10221 /* Under some conditions stdout may not be connected and
10222 * fileno(stdout) may point to an invalid file descriptor. For example
10223 * GUI apps don't have valid standard streams by default.
10224 *
10225 * If this happens, and the optional fd argument is not present,
10226 * the ioctl below will fail returning EBADF. This is what we want.
10227 */
10228
10229 if (!PyArg_ParseTuple(args, "|i", &fd))
10230 return NULL;
10231
10232#ifdef TERMSIZE_USE_IOCTL
10233 {
10234 struct winsize w;
10235 if (ioctl(fd, TIOCGWINSZ, &w))
10236 return PyErr_SetFromErrno(PyExc_OSError);
10237 columns = w.ws_col;
10238 lines = w.ws_row;
10239 }
10240#endif /* TERMSIZE_USE_IOCTL */
10241
10242#ifdef TERMSIZE_USE_CONIO
10243 {
10244 DWORD nhandle;
10245 HANDLE handle;
10246 CONSOLE_SCREEN_BUFFER_INFO csbi;
10247 switch (fd) {
10248 case 0: nhandle = STD_INPUT_HANDLE;
10249 break;
10250 case 1: nhandle = STD_OUTPUT_HANDLE;
10251 break;
10252 case 2: nhandle = STD_ERROR_HANDLE;
10253 break;
10254 default:
10255 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10256 }
10257 handle = GetStdHandle(nhandle);
10258 if (handle == NULL)
10259 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10260 if (handle == INVALID_HANDLE_VALUE)
10261 return PyErr_SetFromWindowsErr(0);
10262
10263 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10264 return PyErr_SetFromWindowsErr(0);
10265
10266 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10267 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10268 }
10269#endif /* TERMSIZE_USE_CONIO */
10270
10271 termsize = PyStructSequence_New(&TerminalSizeType);
10272 if (termsize == NULL)
10273 return NULL;
10274 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10275 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10276 if (PyErr_Occurred()) {
10277 Py_DECREF(termsize);
10278 return NULL;
10279 }
10280 return termsize;
10281}
10282#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10283
10284
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010285static PyMethodDef posix_methods[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010286 {"access", (PyCFunction)posix_access,
10287 METH_VARARGS | METH_KEYWORDS,
10288 posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010289#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010290 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010291#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010292 {"chdir", (PyCFunction)posix_chdir,
10293 METH_VARARGS | METH_KEYWORDS,
10294 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010295#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010296 {"chflags", (PyCFunction)posix_chflags,
10297 METH_VARARGS | METH_KEYWORDS,
10298 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010299#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010300 {"chmod", (PyCFunction)posix_chmod,
10301 METH_VARARGS | METH_KEYWORDS,
10302 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010303#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010304 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010305#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010306#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070010307 {"chown", (PyCFunction)posix_chown,
10308 METH_VARARGS | METH_KEYWORDS,
10309 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010310#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010311#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010312 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010313#endif /* HAVE_LCHMOD */
10314#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010315 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010316#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010317#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010318 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010319#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010320#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010321 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010322#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010323#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010324 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010325#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010326#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010327 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010328#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010329#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010330 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10331 METH_NOARGS, posix_getcwd__doc__},
10332 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10333 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010334#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010335#if defined(HAVE_LINK) || defined(MS_WINDOWS)
10336 {"link", (PyCFunction)posix_link,
10337 METH_VARARGS | METH_KEYWORDS,
10338 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010339#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010340 {"listdir", (PyCFunction)posix_listdir,
10341 METH_VARARGS | METH_KEYWORDS,
10342 posix_listdir__doc__},
10343 {"lstat", (PyCFunction)posix_lstat,
10344 METH_VARARGS | METH_KEYWORDS,
10345 posix_lstat__doc__},
10346 {"mkdir", (PyCFunction)posix_mkdir,
10347 METH_VARARGS | METH_KEYWORDS,
10348 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010349#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010350 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000010351#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010352#ifdef HAVE_GETPRIORITY
10353 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10354#endif /* HAVE_GETPRIORITY */
10355#ifdef HAVE_SETPRIORITY
10356 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10357#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010358#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070010359 {"readlink", (PyCFunction)posix_readlink,
10360 METH_VARARGS | METH_KEYWORDS,
10361 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010362#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010363#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010364 {"readlink", (PyCFunction)win_readlink,
10365 METH_VARARGS | METH_KEYWORDS,
10366 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010367#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010368 {"rename", (PyCFunction)posix_rename,
10369 METH_VARARGS | METH_KEYWORDS,
10370 posix_rename__doc__},
10371 {"replace", (PyCFunction)posix_replace,
10372 METH_VARARGS | METH_KEYWORDS,
10373 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070010374 {"rmdir", (PyCFunction)posix_rmdir,
10375 METH_VARARGS | METH_KEYWORDS,
10376 posix_rmdir__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010377 {"stat", (PyCFunction)posix_stat,
10378 METH_VARARGS | METH_KEYWORDS,
10379 posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010380 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010381#if defined(HAVE_SYMLINK)
10382 {"symlink", (PyCFunction)posix_symlink,
10383 METH_VARARGS | METH_KEYWORDS,
10384 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010385#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000010386#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010387 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010388#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010389 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010390#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010391 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010392#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010393 {"unlink", (PyCFunction)posix_unlink,
10394 METH_VARARGS | METH_KEYWORDS,
10395 posix_unlink__doc__},
10396 {"remove", (PyCFunction)posix_unlink,
10397 METH_VARARGS | METH_KEYWORDS,
10398 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070010399 {"utime", (PyCFunction)posix_utime,
10400 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000010401#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010402 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010403#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010404 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010405#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010406 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010407 {"execve", (PyCFunction)posix_execve,
10408 METH_VARARGS | METH_KEYWORDS,
10409 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010410#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000010411#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010412 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10413 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +000010414#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010415#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010416 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010417#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010418#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010419 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010420#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010421#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010422#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010423 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
10424 {"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 +020010425#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010426#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010427 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010428#endif
10429#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010430 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010431#endif
10432#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010433 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010434#endif
10435#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010436 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010437#endif
10438#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010439 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010440#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010441 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050010442#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010443 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
10444 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
10445#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010446#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010447#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000010448 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010449#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000010450#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010451 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000010452#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000010453#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010454 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000010455#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010456#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010457 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000010458#endif /* HAVE_GETEUID */
10459#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010460 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010461#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020010462#ifdef HAVE_GETGROUPLIST
10463 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
10464#endif
Fred Drakec9680921999-12-13 16:37:25 +000010465#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010466 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010467#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010468 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010469#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010470 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010471#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010472#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010473 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010474#endif /* HAVE_GETPPID */
10475#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010476 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010477#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000010478#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010479 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000010480#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000010481#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000010482 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010483#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010484#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000010485 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010486#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000010487#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010488 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000010489#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000010490#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010491 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
10492 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000010493#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010494#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010495 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010496#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010497#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010498 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010499#endif /* HAVE_SETEUID */
10500#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010501 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010502#endif /* HAVE_SETEGID */
10503#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010504 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010505#endif /* HAVE_SETREUID */
10506#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010507 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010508#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010509#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010510 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010511#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010512#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010513 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010514#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000010515#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010516 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000010517#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000010518#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010519 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000010520#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010521#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010522 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010523#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010524#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010525 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010526#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010527#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010010528 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010529#endif /* HAVE_WAIT3 */
10530#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010010531 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010532#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010533#if defined(HAVE_WAITID) && !defined(__APPLE__)
10534 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
10535#endif
Tim Petersab034fa2002-02-01 11:27:43 +000010536#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010537 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010538#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010539#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010540 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010541#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010542#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010543 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010544#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010545#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010546 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010547#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010548#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010549 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010550#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010551#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010552 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010553#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010554 {"open", (PyCFunction)posix_open,\
10555 METH_VARARGS | METH_KEYWORDS,
10556 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010557 {"close", posix_close, METH_VARARGS, posix_close__doc__},
10558 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
10559 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
10560 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
10561 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010562#ifdef HAVE_LOCKF
10563 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
10564#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010565 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
10566 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010567#ifdef HAVE_READV
10568 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
10569#endif
10570#ifdef HAVE_PREAD
10571 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
10572#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010573 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010574#ifdef HAVE_WRITEV
10575 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
10576#endif
10577#ifdef HAVE_PWRITE
10578 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
10579#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000010580#ifdef HAVE_SENDFILE
10581 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
10582 posix_sendfile__doc__},
10583#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010010584 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010585 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010586#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010587 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010588#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010589#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020010590 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010591#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010592#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070010593 {"mkfifo", (PyCFunction)posix_mkfifo,
10594 METH_VARARGS | METH_KEYWORDS,
10595 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010596#endif
Neal Norwitz11690112002-07-30 01:08:28 +000010597#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010598 {"mknod", (PyCFunction)posix_mknod,
10599 METH_VARARGS | METH_KEYWORDS,
10600 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000010601#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010602#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000010603 {"major", posix_major, METH_VARARGS, posix_major__doc__},
10604 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
10605 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010606#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010607#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000010608 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010609#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010610#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020010611 {"truncate", (PyCFunction)posix_truncate,
10612 METH_VARARGS | METH_KEYWORDS,
10613 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010614#endif
10615#ifdef HAVE_POSIX_FALLOCATE
10616 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
10617#endif
10618#ifdef HAVE_POSIX_FADVISE
10619 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
10620#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010621#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010622 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010623#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010624#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010625 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000010626#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010627 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010628#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000010629 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010630#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010631#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010632 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010633#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010634#ifdef HAVE_SYNC
10635 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
10636#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010637#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010638 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010639#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000010640#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010641#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000010642 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000010643#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010644#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000010645 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010646#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000010647#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000010648 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010649#endif /* WIFSTOPPED */
10650#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000010651 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010652#endif /* WIFSIGNALED */
10653#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000010654 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010655#endif /* WIFEXITED */
10656#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000010657 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010658#endif /* WEXITSTATUS */
10659#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010660 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010661#endif /* WTERMSIG */
10662#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010663 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010664#endif /* WSTOPSIG */
10665#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000010666#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000010667 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010668#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000010669#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010670 {"statvfs", (PyCFunction)posix_statvfs,
10671 METH_VARARGS | METH_KEYWORDS,
10672 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010673#endif
Fred Drakec9680921999-12-13 16:37:25 +000010674#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000010675 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010676#endif
10677#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010678 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010679#endif
10680#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010681 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010682#endif
10683#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020010684 {"pathconf", (PyCFunction)posix_pathconf,
10685 METH_VARARGS | METH_KEYWORDS,
10686 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010687#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010688 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010689#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010690 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000010691 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050010692 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010693 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000010694#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000010695#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000010696 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000010697#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010010698 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010699#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010700 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010701#endif
10702#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010703 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010704#endif
10705#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010706 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010707#endif
10708#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010709 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010710#endif
10711
Benjamin Peterson9428d532011-09-14 11:45:52 -040010712#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010713 {"setxattr", (PyCFunction)posix_setxattr,
10714 METH_VARARGS | METH_KEYWORDS,
10715 posix_setxattr__doc__},
10716 {"getxattr", (PyCFunction)posix_getxattr,
10717 METH_VARARGS | METH_KEYWORDS,
10718 posix_getxattr__doc__},
10719 {"removexattr", (PyCFunction)posix_removexattr,
10720 METH_VARARGS | METH_KEYWORDS,
10721 posix_removexattr__doc__},
10722 {"listxattr", (PyCFunction)posix_listxattr,
10723 METH_VARARGS | METH_KEYWORDS,
10724 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040010725#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010726#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10727 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
10728#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010729 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010730};
10731
10732
Barry Warsaw4a342091996-12-19 23:50:02 +000010733static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010734ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000010735{
Victor Stinner8c62be82010-05-06 00:08:46 +000010736 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000010737}
10738
Brian Curtin52173d42010-12-02 18:29:18 +000010739#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000010740static int
Brian Curtin52173d42010-12-02 18:29:18 +000010741enable_symlink()
10742{
10743 HANDLE tok;
10744 TOKEN_PRIVILEGES tok_priv;
10745 LUID luid;
10746 int meth_idx = 0;
10747
10748 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000010749 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000010750
10751 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000010752 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000010753
10754 tok_priv.PrivilegeCount = 1;
10755 tok_priv.Privileges[0].Luid = luid;
10756 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
10757
10758 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
10759 sizeof(TOKEN_PRIVILEGES),
10760 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000010761 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000010762
Brian Curtin3b4499c2010-12-28 14:31:47 +000010763 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
10764 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000010765}
10766#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
10767
Barry Warsaw4a342091996-12-19 23:50:02 +000010768static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000010769all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000010770{
Guido van Rossum94f6f721999-01-06 18:42:14 +000010771#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010772 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010773#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010774#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010775 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010776#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010777#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010778 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010779#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010780#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010781 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010782#endif
Fred Drakec9680921999-12-13 16:37:25 +000010783#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010784 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000010785#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010786#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010787 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010788#endif
Fred Drake106c1a02002-04-23 15:58:02 +000010789#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000010790 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000010791#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000010792#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000010793 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010794#endif
Fred Drake106c1a02002-04-23 15:58:02 +000010795#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000010796 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000010797#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000010798#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000010799 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010800#endif
10801#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000010802 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010803#endif
10804#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000010805 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010806#endif
10807#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000010808 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010809#endif
10810#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010811 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010812#endif
10813#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000010814 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010815#endif
10816#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010817 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010818#endif
10819#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010820 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010821#endif
10822#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010823 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010824#endif
10825#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010826 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010827#endif
10828#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000010829 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010830#endif
10831#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000010832 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010833#endif
10834#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010835 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010836#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000010837#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000010838 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000010839#endif
10840#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000010841 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000010842#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020010843#ifdef O_XATTR
10844 if (ins(d, "O_XATTR", (long)O_XATTR)) return -1;
10845#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010846#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000010847 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010848#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000010849#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010850 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000010851#endif
10852#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010853 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000010854#endif
Jesus Ceacf381202012-04-24 20:44:40 +020010855#ifdef O_EXEC
10856 if (ins(d, "O_EXEC", (long)O_EXEC)) return -1;
10857#endif
10858#ifdef O_SEARCH
10859 if (ins(d, "O_SEARCH", (long)O_SEARCH)) return -1;
10860#endif
10861#ifdef O_TTY_INIT
10862 if (ins(d, "O_TTY_INIT", (long)O_TTY_INIT)) return -1;
10863#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010864#ifdef PRIO_PROCESS
10865 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
10866#endif
10867#ifdef PRIO_PGRP
10868 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
10869#endif
10870#ifdef PRIO_USER
10871 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
10872#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020010873#ifdef O_CLOEXEC
10874 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
10875#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020010876#ifdef O_ACCMODE
10877 if (ins(d, "O_ACCMODE", (long)O_ACCMODE)) return -1;
10878#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010879
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010880
Jesus Cea94363612012-06-22 18:32:07 +020010881#ifdef SEEK_HOLE
10882 if (ins(d, "SEEK_HOLE", (long)SEEK_HOLE)) return -1;
10883#endif
10884#ifdef SEEK_DATA
10885 if (ins(d, "SEEK_DATA", (long)SEEK_DATA)) return -1;
10886#endif
10887
Tim Peters5aa91602002-01-30 05:46:57 +000010888/* MS Windows */
10889#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010890 /* Don't inherit in child processes. */
10891 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010892#endif
10893#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000010894 /* Optimize for short life (keep in memory). */
10895 /* MS forgot to define this one with a non-underscore form too. */
10896 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010897#endif
10898#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000010899 /* Automatically delete when last handle is closed. */
10900 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010901#endif
10902#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000010903 /* Optimize for random access. */
10904 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010905#endif
10906#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010907 /* Optimize for sequential access. */
10908 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010909#endif
10910
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010911/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000010912#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010913 /* Send a SIGIO signal whenever input or output
10914 becomes available on file descriptor */
10915 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000010916#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010917#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010918 /* Direct disk access. */
10919 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010920#endif
10921#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000010922 /* Must be a directory. */
10923 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010924#endif
10925#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000010926 /* Do not follow links. */
10927 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010928#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020010929#ifdef O_NOLINKS
10930 /* Fails if link count of the named file is greater than 1 */
10931 if (ins(d, "O_NOLINKS", (long)O_NOLINKS)) return -1;
10932#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000010933#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010934 /* Do not update the access time. */
10935 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000010936#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000010937
Victor Stinner8c62be82010-05-06 00:08:46 +000010938 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010939#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010940 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010941#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010942#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010943 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010944#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010945#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000010946 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010947#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010948#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010949 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010950#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010951#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000010952 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010953#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010954#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000010955 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010956#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010957#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010958 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010959#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010960#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000010961 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010962#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010963#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000010964 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010965#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010966#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000010967 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010968#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010969#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000010970 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010971#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010972#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000010973 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010974#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010975#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000010976 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010977#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010978#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000010979 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010980#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010981#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010982 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010983#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010984#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010985 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010986#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010987#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000010988 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010989#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010990
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000010991 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000010992#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000010993 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000010994#endif /* ST_RDONLY */
10995#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000010996 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000010997#endif /* ST_NOSUID */
10998
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000010999 /* FreeBSD sendfile() constants */
11000#ifdef SF_NODISKIO
11001 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
11002#endif
11003#ifdef SF_MNOWAIT
11004 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
11005#endif
11006#ifdef SF_SYNC
11007 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
11008#endif
11009
Ross Lagerwall7807c352011-03-17 20:20:30 +020011010 /* constants for posix_fadvise */
11011#ifdef POSIX_FADV_NORMAL
11012 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
11013#endif
11014#ifdef POSIX_FADV_SEQUENTIAL
11015 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
11016#endif
11017#ifdef POSIX_FADV_RANDOM
11018 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
11019#endif
11020#ifdef POSIX_FADV_NOREUSE
11021 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
11022#endif
11023#ifdef POSIX_FADV_WILLNEED
11024 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
11025#endif
11026#ifdef POSIX_FADV_DONTNEED
11027 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
11028#endif
11029
11030 /* constants for waitid */
11031#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
11032 if (ins(d, "P_PID", (long)P_PID)) return -1;
11033 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
11034 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
11035#endif
11036#ifdef WEXITED
11037 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
11038#endif
11039#ifdef WNOWAIT
11040 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
11041#endif
11042#ifdef WSTOPPED
11043 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
11044#endif
11045#ifdef CLD_EXITED
11046 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
11047#endif
11048#ifdef CLD_DUMPED
11049 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
11050#endif
11051#ifdef CLD_TRAPPED
11052 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
11053#endif
11054#ifdef CLD_CONTINUED
11055 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
11056#endif
11057
11058 /* constants for lockf */
11059#ifdef F_LOCK
11060 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
11061#endif
11062#ifdef F_TLOCK
11063 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
11064#endif
11065#ifdef F_ULOCK
11066 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
11067#endif
11068#ifdef F_TEST
11069 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
11070#endif
11071
Guido van Rossum246bc171999-02-01 23:54:31 +000011072#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000011073 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
11074 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
11075 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
11076 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
11077 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011078#endif
11079
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011080#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011081 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011082 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11083 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11084#ifdef SCHED_SPORADIC
11085 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
11086#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011087#ifdef SCHED_BATCH
11088 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11089#endif
11090#ifdef SCHED_IDLE
11091 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11092#endif
11093#ifdef SCHED_RESET_ON_FORK
11094 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11095#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011096#ifdef SCHED_SYS
11097 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11098#endif
11099#ifdef SCHED_IA
11100 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11101#endif
11102#ifdef SCHED_FSS
11103 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11104#endif
11105#ifdef SCHED_FX
11106 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11107#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011108#endif
11109
Benjamin Peterson9428d532011-09-14 11:45:52 -040011110#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011111 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11112 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11113 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11114#endif
11115
Victor Stinner8b905bd2011-10-25 13:34:04 +020011116#ifdef RTLD_LAZY
11117 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11118#endif
11119#ifdef RTLD_NOW
11120 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11121#endif
11122#ifdef RTLD_GLOBAL
11123 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11124#endif
11125#ifdef RTLD_LOCAL
11126 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11127#endif
11128#ifdef RTLD_NODELETE
11129 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11130#endif
11131#ifdef RTLD_NOLOAD
11132 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11133#endif
11134#ifdef RTLD_DEEPBIND
11135 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11136#endif
11137
Victor Stinner8c62be82010-05-06 00:08:46 +000011138 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011139}
11140
11141
Tim Peters5aa91602002-01-30 05:46:57 +000011142#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011143#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011144#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011145
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011146#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011147#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011148#define MODNAME "posix"
11149#endif
11150
Martin v. Löwis1a214512008-06-11 05:26:20 +000011151static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011152 PyModuleDef_HEAD_INIT,
11153 MODNAME,
11154 posix__doc__,
11155 -1,
11156 posix_methods,
11157 NULL,
11158 NULL,
11159 NULL,
11160 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011161};
11162
11163
Larry Hastings9cf065c2012-06-22 16:30:09 -070011164static char *have_functions[] = {
11165
11166#ifdef HAVE_FACCESSAT
11167 "HAVE_FACCESSAT",
11168#endif
11169
11170#ifdef HAVE_FCHDIR
11171 "HAVE_FCHDIR",
11172#endif
11173
11174#ifdef HAVE_FCHMOD
11175 "HAVE_FCHMOD",
11176#endif
11177
11178#ifdef HAVE_FCHMODAT
11179 "HAVE_FCHMODAT",
11180#endif
11181
11182#ifdef HAVE_FCHOWN
11183 "HAVE_FCHOWN",
11184#endif
11185
11186#ifdef HAVE_FEXECVE
11187 "HAVE_FEXECVE",
11188#endif
11189
11190#ifdef HAVE_FDOPENDIR
11191 "HAVE_FDOPENDIR",
11192#endif
11193
Georg Brandl306336b2012-06-24 12:55:33 +020011194#ifdef HAVE_FPATHCONF
11195 "HAVE_FPATHCONF",
11196#endif
11197
Larry Hastings9cf065c2012-06-22 16:30:09 -070011198#ifdef HAVE_FSTATAT
11199 "HAVE_FSTATAT",
11200#endif
11201
11202#ifdef HAVE_FSTATVFS
11203 "HAVE_FSTATVFS",
11204#endif
11205
Georg Brandl306336b2012-06-24 12:55:33 +020011206#ifdef HAVE_FTRUNCATE
11207 "HAVE_FTRUNCATE",
11208#endif
11209
Larry Hastings9cf065c2012-06-22 16:30:09 -070011210#ifdef HAVE_FUTIMENS
11211 "HAVE_FUTIMENS",
11212#endif
11213
11214#ifdef HAVE_FUTIMES
11215 "HAVE_FUTIMES",
11216#endif
11217
11218#ifdef HAVE_FUTIMESAT
11219 "HAVE_FUTIMESAT",
11220#endif
11221
11222#ifdef HAVE_LINKAT
11223 "HAVE_LINKAT",
11224#endif
11225
11226#ifdef HAVE_LCHFLAGS
11227 "HAVE_LCHFLAGS",
11228#endif
11229
11230#ifdef HAVE_LCHMOD
11231 "HAVE_LCHMOD",
11232#endif
11233
11234#ifdef HAVE_LCHOWN
11235 "HAVE_LCHOWN",
11236#endif
11237
11238#ifdef HAVE_LSTAT
11239 "HAVE_LSTAT",
11240#endif
11241
11242#ifdef HAVE_LUTIMES
11243 "HAVE_LUTIMES",
11244#endif
11245
11246#ifdef HAVE_MKDIRAT
11247 "HAVE_MKDIRAT",
11248#endif
11249
11250#ifdef HAVE_MKFIFOAT
11251 "HAVE_MKFIFOAT",
11252#endif
11253
11254#ifdef HAVE_MKNODAT
11255 "HAVE_MKNODAT",
11256#endif
11257
11258#ifdef HAVE_OPENAT
11259 "HAVE_OPENAT",
11260#endif
11261
11262#ifdef HAVE_READLINKAT
11263 "HAVE_READLINKAT",
11264#endif
11265
11266#ifdef HAVE_RENAMEAT
11267 "HAVE_RENAMEAT",
11268#endif
11269
11270#ifdef HAVE_SYMLINKAT
11271 "HAVE_SYMLINKAT",
11272#endif
11273
11274#ifdef HAVE_UNLINKAT
11275 "HAVE_UNLINKAT",
11276#endif
11277
11278#ifdef HAVE_UTIMENSAT
11279 "HAVE_UTIMENSAT",
11280#endif
11281
11282#ifdef MS_WINDOWS
11283 "MS_WINDOWS",
11284#endif
11285
11286 NULL
11287};
11288
11289
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011290PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011291INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011292{
Victor Stinner8c62be82010-05-06 00:08:46 +000011293 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011294 PyObject *list;
11295 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000011296
Brian Curtin52173d42010-12-02 18:29:18 +000011297#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011298 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011299#endif
11300
Victor Stinner8c62be82010-05-06 00:08:46 +000011301 m = PyModule_Create(&posixmodule);
11302 if (m == NULL)
11303 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011304
Victor Stinner8c62be82010-05-06 00:08:46 +000011305 /* Initialize environ dictionary */
11306 v = convertenviron();
11307 Py_XINCREF(v);
11308 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11309 return NULL;
11310 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011311
Victor Stinner8c62be82010-05-06 00:08:46 +000011312 if (all_ins(m))
11313 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011314
Victor Stinner8c62be82010-05-06 00:08:46 +000011315 if (setup_confname_tables(m))
11316 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011317
Victor Stinner8c62be82010-05-06 00:08:46 +000011318 Py_INCREF(PyExc_OSError);
11319 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011320
Guido van Rossumb3d39562000-01-31 18:41:26 +000011321#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011322 if (posix_putenv_garbage == NULL)
11323 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011324#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011325
Victor Stinner8c62be82010-05-06 00:08:46 +000011326 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011327#if defined(HAVE_WAITID) && !defined(__APPLE__)
11328 waitid_result_desc.name = MODNAME ".waitid_result";
11329 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
11330#endif
11331
Victor Stinner8c62be82010-05-06 00:08:46 +000011332 stat_result_desc.name = MODNAME ".stat_result";
11333 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11334 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11335 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
11336 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
11337 structseq_new = StatResultType.tp_new;
11338 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011339
Victor Stinner8c62be82010-05-06 00:08:46 +000011340 statvfs_result_desc.name = MODNAME ".statvfs_result";
11341 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011342#ifdef NEED_TICKS_PER_SECOND
11343# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011344 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011345# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011346 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011347# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011348 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011349# endif
11350#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011351
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050011352#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011353 sched_param_desc.name = MODNAME ".sched_param";
11354 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
11355 SchedParamType.tp_new = sched_param_new;
11356#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011357
11358 /* initialize TerminalSize_info */
11359 PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc);
Victor Stinner8c62be82010-05-06 00:08:46 +000011360 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011361#if defined(HAVE_WAITID) && !defined(__APPLE__)
11362 Py_INCREF((PyObject*) &WaitidResultType);
11363 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
11364#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011365 Py_INCREF((PyObject*) &StatResultType);
11366 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11367 Py_INCREF((PyObject*) &StatVFSResultType);
11368 PyModule_AddObject(m, "statvfs_result",
11369 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011370
11371#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011372 Py_INCREF(&SchedParamType);
11373 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011374#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011375
Larry Hastings605a62d2012-06-24 04:33:36 -070011376 times_result_desc.name = MODNAME ".times_result";
11377 PyStructSequence_InitType(&TimesResultType, &times_result_desc);
11378 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
11379
11380 uname_result_desc.name = MODNAME ".uname_result";
11381 PyStructSequence_InitType(&UnameResultType, &uname_result_desc);
11382 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
11383
Thomas Wouters477c8d52006-05-27 19:21:47 +000011384#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000011385 /*
11386 * Step 2 of weak-linking support on Mac OS X.
11387 *
11388 * The code below removes functions that are not available on the
11389 * currently active platform.
11390 *
11391 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070011392 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000011393 * OSX 10.4.
11394 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011395#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011396 if (fstatvfs == NULL) {
11397 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
11398 return NULL;
11399 }
11400 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011401#endif /* HAVE_FSTATVFS */
11402
11403#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011404 if (statvfs == NULL) {
11405 if (PyObject_DelAttrString(m, "statvfs") == -1) {
11406 return NULL;
11407 }
11408 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011409#endif /* HAVE_STATVFS */
11410
11411# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011412 if (lchown == NULL) {
11413 if (PyObject_DelAttrString(m, "lchown") == -1) {
11414 return NULL;
11415 }
11416 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011417#endif /* HAVE_LCHOWN */
11418
11419
11420#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011421
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020011422 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011423 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
11424
Larry Hastings6fe20b32012-04-19 15:07:49 -070011425 billion = PyLong_FromLong(1000000000);
11426 if (!billion)
11427 return NULL;
11428
Larry Hastings9cf065c2012-06-22 16:30:09 -070011429 /* suppress "function not used" warnings */
11430 {
11431 int ignored;
11432 fd_specified("", -1);
11433 follow_symlinks_specified("", 1);
11434 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
11435 dir_fd_converter(Py_None, &ignored);
11436 dir_fd_unavailable(Py_None, &ignored);
11437 }
11438
11439 /*
11440 * provide list of locally available functions
11441 * so os.py can populate support_* lists
11442 */
11443 list = PyList_New(0);
11444 if (!list)
11445 return NULL;
11446 for (trace = have_functions; *trace; trace++) {
11447 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
11448 if (!unicode)
11449 return NULL;
11450 if (PyList_Append(list, unicode))
11451 return NULL;
11452 Py_DECREF(unicode);
11453 }
11454 PyModule_AddObject(m, "_have_functions", list);
11455
11456 initialized = 1;
11457
Victor Stinner8c62be82010-05-06 00:08:46 +000011458 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011459
Guido van Rossumb6775db1994-08-01 11:34:53 +000011460}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011461
11462#ifdef __cplusplus
11463}
11464#endif