blob: 6830684434b7e21eb81d30ec7188fca476c86b4e [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
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003252#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003253static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003254_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003255{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003256 static char *keywords[] = {"path", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07003257 PyObject *v;
3258 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3259 BOOL result;
3260 WIN32_FIND_DATA FileData;
3261 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
3262 char *bufptr = namebuf;
3263 /* only claim to have space for MAX_PATH */
3264 Py_ssize_t len = sizeof(namebuf)-5;
3265 PyObject *po = NULL;
3266 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003267
Gregory P. Smith40a21602013-03-20 20:52:50 -07003268 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003269 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003270 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003271
Gregory P. Smith40a21602013-03-20 20:52:50 -07003272 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003273 po_wchars = L".";
3274 len = 1;
3275 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003276 po_wchars = path->wide;
3277 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003278 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003279 /* The +5 is so we can append "\\*.*\0" */
Victor Stinner8c62be82010-05-06 00:08:46 +00003280 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
3281 if (!wnamebuf) {
3282 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003283 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003284 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003285 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003286 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003287 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00003288 if (wch != L'/' && wch != L'\\' && wch != L':')
3289 wnamebuf[len++] = L'\\';
3290 wcscpy(wnamebuf + len, L"*.*");
3291 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003292 if ((list = PyList_New(0)) == NULL) {
3293 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003294 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003295 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003296 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003297 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003298 if (hFindFile == INVALID_HANDLE_VALUE) {
3299 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003300 if (error == ERROR_FILE_NOT_FOUND)
3301 goto exit;
3302 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003303 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003304 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003305 }
3306 do {
3307 /* Skip over . and .. */
3308 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3309 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003310 v = PyUnicode_FromWideChar(wFileData.cFileName,
3311 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003312 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003313 Py_DECREF(list);
3314 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003315 break;
3316 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003317 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003318 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003319 Py_DECREF(list);
3320 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003321 break;
3322 }
3323 Py_DECREF(v);
3324 }
3325 Py_BEGIN_ALLOW_THREADS
3326 result = FindNextFileW(hFindFile, &wFileData);
3327 Py_END_ALLOW_THREADS
3328 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3329 it got to the end of the directory. */
3330 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003331 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003332 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003333 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003334 }
3335 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003336
Larry Hastings9cf065c2012-06-22 16:30:09 -07003337 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003338 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003339 strcpy(namebuf, path->narrow);
3340 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003341 if (len > 0) {
3342 char ch = namebuf[len-1];
3343 if (ch != SEP && ch != ALTSEP && ch != ':')
3344 namebuf[len++] = '/';
3345 strcpy(namebuf + len, "*.*");
3346 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003347
Larry Hastings9cf065c2012-06-22 16:30:09 -07003348 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003349 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003350
Antoine Pitroub73caab2010-08-09 23:39:31 +00003351 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003352 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003353 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003354 if (hFindFile == INVALID_HANDLE_VALUE) {
3355 int error = GetLastError();
3356 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003357 goto exit;
3358 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003359 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003360 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003361 }
3362 do {
3363 /* Skip over . and .. */
3364 if (strcmp(FileData.cFileName, ".") != 0 &&
3365 strcmp(FileData.cFileName, "..") != 0) {
3366 v = PyBytes_FromString(FileData.cFileName);
3367 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003368 Py_DECREF(list);
3369 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003370 break;
3371 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003372 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003373 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003374 Py_DECREF(list);
3375 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003376 break;
3377 }
3378 Py_DECREF(v);
3379 }
3380 Py_BEGIN_ALLOW_THREADS
3381 result = FindNextFile(hFindFile, &FileData);
3382 Py_END_ALLOW_THREADS
3383 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3384 it got to the end of the directory. */
3385 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003386 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003387 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003388 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003389 }
3390 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003391
Larry Hastings9cf065c2012-06-22 16:30:09 -07003392exit:
3393 if (hFindFile != INVALID_HANDLE_VALUE) {
3394 if (FindClose(hFindFile) == FALSE) {
3395 if (list != NULL) {
3396 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003397 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003398 }
3399 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003400 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003401 if (wnamebuf)
3402 free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003403
Larry Hastings9cf065c2012-06-22 16:30:09 -07003404 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003405} /* end of _listdir_windows_no_opendir */
3406
3407#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3408
3409static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003410_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003411{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003412 int fd = -1;
3413
3414 PyObject *v;
3415 DIR *dirp = NULL;
3416 struct dirent *ep;
3417 int return_str; /* if false, return bytes */
3418
Victor Stinner8c62be82010-05-06 00:08:46 +00003419 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003420#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003421 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003422 /* closedir() closes the FD, so we duplicate it */
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003423 Py_BEGIN_ALLOW_THREADS
Gregory P. Smith40a21602013-03-20 20:52:50 -07003424 fd = dup(path->fd);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003425 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003426
3427 if (fd == -1) {
3428 list = posix_error();
3429 goto exit;
3430 }
3431
Larry Hastingsfdaea062012-06-25 04:42:23 -07003432 return_str = 1;
3433
Larry Hastings9cf065c2012-06-22 16:30:09 -07003434 Py_BEGIN_ALLOW_THREADS
3435 dirp = fdopendir(fd);
3436 Py_END_ALLOW_THREADS
3437 }
3438 else
3439#endif
3440 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003441 char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003442 if (path->narrow) {
3443 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003444 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003445 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003446 }
3447 else {
3448 name = ".";
3449 return_str = 1;
3450 }
3451
Larry Hastings9cf065c2012-06-22 16:30:09 -07003452 Py_BEGIN_ALLOW_THREADS
3453 dirp = opendir(name);
3454 Py_END_ALLOW_THREADS
3455 }
3456
3457 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003458 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003459 goto exit;
3460 }
3461 if ((list = PyList_New(0)) == NULL) {
3462 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003463 }
3464 for (;;) {
3465 errno = 0;
3466 Py_BEGIN_ALLOW_THREADS
3467 ep = readdir(dirp);
3468 Py_END_ALLOW_THREADS
3469 if (ep == NULL) {
3470 if (errno == 0) {
3471 break;
3472 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003473 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003474 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003475 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003476 }
3477 }
3478 if (ep->d_name[0] == '.' &&
3479 (NAMLEN(ep) == 1 ||
3480 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3481 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003482 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003483 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3484 else
3485 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003486 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003487 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003488 break;
3489 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003490 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003491 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003492 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003493 break;
3494 }
3495 Py_DECREF(v);
3496 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003497
Larry Hastings9cf065c2012-06-22 16:30:09 -07003498exit:
3499 if (dirp != NULL) {
3500 Py_BEGIN_ALLOW_THREADS
3501 if (fd > -1)
3502 rewinddir(dirp);
3503 closedir(dirp);
3504 Py_END_ALLOW_THREADS
3505 }
3506
Larry Hastings9cf065c2012-06-22 16:30:09 -07003507 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003508} /* end of _posix_listdir */
3509#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003510
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003511static PyObject *
3512posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
3513{
Gregory P. Smith40a21602013-03-20 20:52:50 -07003514 path_t path;
3515 PyObject *list = NULL;
3516 static char *keywords[] = {"path", NULL};
3517 PyObject *return_value;
3518
3519 memset(&path, 0, sizeof(path));
3520 path.function_name = "listdir";
3521 path.nullable = 1;
3522#ifdef HAVE_FDOPENDIR
3523 path.allow_fd = 1;
3524 path.fd = -1;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003525#endif
Gregory P. Smith40a21602013-03-20 20:52:50 -07003526
3527 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3528 path_converter, &path)) {
3529 return NULL;
3530 }
3531
3532#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3533 return_value = _listdir_windows_no_opendir(&path, list);
3534#else
3535 return_value = _posix_listdir(&path, list);
3536#endif
3537 path_cleanup(&path);
3538 return return_value;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003539}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003540
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003541#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003542/* A helper function for abspath on win32 */
3543static PyObject *
3544posix__getfullpathname(PyObject *self, PyObject *args)
3545{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003546 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003547 char outbuf[MAX_PATH*2];
3548 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003549 PyObject *po;
3550
3551 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3552 {
3553 wchar_t *wpath;
3554 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3555 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003556 DWORD result;
3557 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003558
3559 wpath = PyUnicode_AsUnicode(po);
3560 if (wpath == NULL)
3561 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003562 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003563 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003564 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003565 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003566 woutbufp = malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003567 if (!woutbufp)
3568 return PyErr_NoMemory();
3569 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3570 }
3571 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003572 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003573 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003574 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003575 if (woutbufp != woutbuf)
3576 free(woutbufp);
3577 return v;
3578 }
3579 /* Drop the argument parsing error as narrow strings
3580 are also valid. */
3581 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003582
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003583 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3584 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003585 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003586 if (win32_warn_bytes_api())
3587 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003588 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003589 outbuf, &temp)) {
3590 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003591 return NULL;
3592 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003593 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3594 return PyUnicode_Decode(outbuf, strlen(outbuf),
3595 Py_FileSystemDefaultEncoding, NULL);
3596 }
3597 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003598} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003599
Brian Curtind25aef52011-06-13 15:16:04 -05003600
Brian Curtinf5e76d02010-11-24 13:14:05 +00003601
Brian Curtind40e6f72010-07-08 21:39:08 +00003602/* A helper function for samepath on windows */
3603static PyObject *
3604posix__getfinalpathname(PyObject *self, PyObject *args)
3605{
3606 HANDLE hFile;
3607 int buf_size;
3608 wchar_t *target_path;
3609 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003610 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003611 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003612
Victor Stinnereb5657a2011-09-30 01:44:27 +02003613 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003614 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003615 path = PyUnicode_AsUnicode(po);
3616 if (path == NULL)
3617 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003618
3619 if(!check_GetFinalPathNameByHandle()) {
3620 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3621 NotImplementedError. */
3622 return PyErr_Format(PyExc_NotImplementedError,
3623 "GetFinalPathNameByHandle not available on this platform");
3624 }
3625
3626 hFile = CreateFileW(
3627 path,
3628 0, /* desired access */
3629 0, /* share mode */
3630 NULL, /* security attributes */
3631 OPEN_EXISTING,
3632 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3633 FILE_FLAG_BACKUP_SEMANTICS,
3634 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003635
Victor Stinnereb5657a2011-09-30 01:44:27 +02003636 if(hFile == INVALID_HANDLE_VALUE)
3637 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003638
3639 /* We have a good handle to the target, use it to determine the
3640 target path name. */
3641 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3642
3643 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003644 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003645
3646 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
3647 if(!target_path)
3648 return PyErr_NoMemory();
3649
3650 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3651 buf_size, VOLUME_NAME_DOS);
3652 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003653 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003654
3655 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003656 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003657
3658 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003659 result = PyUnicode_FromWideChar(target_path, result_length);
Brian Curtind40e6f72010-07-08 21:39:08 +00003660 free(target_path);
3661 return result;
3662
3663} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003664
Brian Curtin95d028f2011-06-09 09:10:38 -05003665PyDoc_STRVAR(posix__isdir__doc__,
3666"Return true if the pathname refers to an existing directory.");
3667
Brian Curtin9c669cc2011-06-08 18:17:18 -05003668static PyObject *
3669posix__isdir(PyObject *self, PyObject *args)
3670{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003671 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003672 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003673 DWORD attributes;
3674
3675 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003676 wchar_t *wpath = PyUnicode_AsUnicode(po);
3677 if (wpath == NULL)
3678 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003679
3680 attributes = GetFileAttributesW(wpath);
3681 if (attributes == INVALID_FILE_ATTRIBUTES)
3682 Py_RETURN_FALSE;
3683 goto check;
3684 }
3685 /* Drop the argument parsing error as narrow strings
3686 are also valid. */
3687 PyErr_Clear();
3688
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003689 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003690 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003691 if (win32_warn_bytes_api())
3692 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003693 attributes = GetFileAttributesA(path);
3694 if (attributes == INVALID_FILE_ATTRIBUTES)
3695 Py_RETURN_FALSE;
3696
3697check:
3698 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3699 Py_RETURN_TRUE;
3700 else
3701 Py_RETURN_FALSE;
3702}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003703#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003704
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003705PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003706"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3707Create a directory.\n\
3708\n\
3709If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3710 and path should be relative; path will then be relative to that directory.\n\
3711dir_fd may not be implemented on your platform.\n\
3712 If it is unavailable, using it will raise a NotImplementedError.\n\
3713\n\
3714The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003715
Barry Warsaw53699e91996-12-10 23:23:01 +00003716static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003717posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003718{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003719 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003720 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003721 int dir_fd = DEFAULT_DIR_FD;
3722 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
3723 PyObject *return_value = NULL;
3724 int result;
3725
3726 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003727 path.function_name = "mkdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003728 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
3729 path_converter, &path, &mode,
3730#ifdef HAVE_MKDIRAT
3731 dir_fd_converter, &dir_fd
3732#else
3733 dir_fd_unavailable, &dir_fd
3734#endif
3735 ))
3736 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003737
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003738#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003739 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003740 if (path.wide)
3741 result = CreateDirectoryW(path.wide, NULL);
3742 else
3743 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003744 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003745
Larry Hastings9cf065c2012-06-22 16:30:09 -07003746 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003747 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003748 goto exit;
3749 }
3750#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003751 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003752#if HAVE_MKDIRAT
3753 if (dir_fd != DEFAULT_DIR_FD)
3754 result = mkdirat(dir_fd, path.narrow, mode);
3755 else
3756#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003757#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003758 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003759#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003760 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003761#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003762 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003763 if (result < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01003764 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003765 goto exit;
3766 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00003767#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003768 return_value = Py_None;
3769 Py_INCREF(Py_None);
3770exit:
3771 path_cleanup(&path);
3772 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003773}
3774
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003775
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003776/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3777#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003778#include <sys/resource.h>
3779#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003780
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003781
3782#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003783PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003784"nice(inc) -> new_priority\n\n\
3785Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003786
Barry Warsaw53699e91996-12-10 23:23:01 +00003787static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003788posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00003789{
Victor Stinner8c62be82010-05-06 00:08:46 +00003790 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00003791
Victor Stinner8c62be82010-05-06 00:08:46 +00003792 if (!PyArg_ParseTuple(args, "i:nice", &increment))
3793 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003794
Victor Stinner8c62be82010-05-06 00:08:46 +00003795 /* There are two flavours of 'nice': one that returns the new
3796 priority (as required by almost all standards out there) and the
3797 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3798 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003799
Victor Stinner8c62be82010-05-06 00:08:46 +00003800 If we are of the nice family that returns the new priority, we
3801 need to clear errno before the call, and check if errno is filled
3802 before calling posix_error() on a returnvalue of -1, because the
3803 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003804
Victor Stinner8c62be82010-05-06 00:08:46 +00003805 errno = 0;
3806 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003807#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003808 if (value == 0)
3809 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003810#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003811 if (value == -1 && errno != 0)
3812 /* either nice() or getpriority() returned an error */
3813 return posix_error();
3814 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003815}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003816#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003817
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003818
3819#ifdef HAVE_GETPRIORITY
3820PyDoc_STRVAR(posix_getpriority__doc__,
3821"getpriority(which, who) -> current_priority\n\n\
3822Get program scheduling priority.");
3823
3824static PyObject *
3825posix_getpriority(PyObject *self, PyObject *args)
3826{
3827 int which, who, retval;
3828
3829 if (!PyArg_ParseTuple(args, "ii", &which, &who))
3830 return NULL;
3831 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003832 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003833 if (errno != 0)
3834 return posix_error();
3835 return PyLong_FromLong((long)retval);
3836}
3837#endif /* HAVE_GETPRIORITY */
3838
3839
3840#ifdef HAVE_SETPRIORITY
3841PyDoc_STRVAR(posix_setpriority__doc__,
3842"setpriority(which, who, prio) -> None\n\n\
3843Set program scheduling priority.");
3844
3845static PyObject *
3846posix_setpriority(PyObject *self, PyObject *args)
3847{
3848 int which, who, prio, retval;
3849
3850 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
3851 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003852 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003853 if (retval == -1)
3854 return posix_error();
3855 Py_RETURN_NONE;
3856}
3857#endif /* HAVE_SETPRIORITY */
3858
3859
Barry Warsaw53699e91996-12-10 23:23:01 +00003860static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003861internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003862{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003863 char *function_name = is_replace ? "replace" : "rename";
3864 path_t src;
3865 path_t dst;
3866 int src_dir_fd = DEFAULT_DIR_FD;
3867 int dst_dir_fd = DEFAULT_DIR_FD;
3868 int dir_fd_specified;
3869 PyObject *return_value = NULL;
3870 char format[24];
3871 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
3872
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003873#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003874 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003875 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003876#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003877 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003878#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003879
3880 memset(&src, 0, sizeof(src));
3881 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01003882 src.function_name = function_name;
3883 dst.function_name = function_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003884 strcpy(format, "O&O&|$O&O&:");
3885 strcat(format, function_name);
3886 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
3887 path_converter, &src,
3888 path_converter, &dst,
3889 dir_fd_converter, &src_dir_fd,
3890 dir_fd_converter, &dst_dir_fd))
3891 return NULL;
3892
3893 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
3894 (dst_dir_fd != DEFAULT_DIR_FD);
3895#ifndef HAVE_RENAMEAT
3896 if (dir_fd_specified) {
3897 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
3898 goto exit;
3899 }
3900#endif
3901
3902 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3903 PyErr_Format(PyExc_ValueError,
3904 "%s: src and dst must be the same type", function_name);
3905 goto exit;
3906 }
3907
3908#ifdef MS_WINDOWS
3909 Py_BEGIN_ALLOW_THREADS
3910 if (src.wide)
3911 result = MoveFileExW(src.wide, dst.wide, flags);
3912 else
3913 result = MoveFileExA(src.narrow, dst.narrow, flags);
3914 Py_END_ALLOW_THREADS
3915
3916 if (!result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01003917 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003918 goto exit;
3919 }
3920
3921#else
3922 Py_BEGIN_ALLOW_THREADS
3923#ifdef HAVE_RENAMEAT
3924 if (dir_fd_specified)
3925 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
3926 else
3927#endif
3928 result = rename(src.narrow, dst.narrow);
3929 Py_END_ALLOW_THREADS
3930
3931 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003932 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003933 goto exit;
3934 }
3935#endif
3936
3937 Py_INCREF(Py_None);
3938 return_value = Py_None;
3939exit:
3940 path_cleanup(&src);
3941 path_cleanup(&dst);
3942 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003943}
3944
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003945PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003946"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
3947Rename a file or directory.\n\
3948\n\
3949If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3950 descriptor open to a directory, and the respective path string (src or dst)\n\
3951 should be relative; the path will then be relative to that directory.\n\
3952src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
3953 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003954
3955static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003956posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003957{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003958 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003959}
3960
3961PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003962"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
3963Rename a file or directory, overwriting the destination.\n\
3964\n\
3965If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3966 descriptor open to a directory, and the respective path string (src or dst)\n\
3967 should be relative; the path will then be relative to that directory.\n\
3968src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
3969 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003970
3971static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003972posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003973{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003974 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003975}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003976
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003977PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003978"rmdir(path, *, dir_fd=None)\n\n\
3979Remove a directory.\n\
3980\n\
3981If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3982 and path should be relative; path will then be relative to that directory.\n\
3983dir_fd may not be implemented on your platform.\n\
3984 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003985
Barry Warsaw53699e91996-12-10 23:23:01 +00003986static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003987posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003988{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003989 path_t path;
3990 int dir_fd = DEFAULT_DIR_FD;
3991 static char *keywords[] = {"path", "dir_fd", NULL};
3992 int result;
3993 PyObject *return_value = NULL;
3994
3995 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003996 path.function_name = "rmdir";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003997 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
3998 path_converter, &path,
3999#ifdef HAVE_UNLINKAT
4000 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004001#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004002 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004003#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004004 ))
4005 return NULL;
4006
4007 Py_BEGIN_ALLOW_THREADS
4008#ifdef MS_WINDOWS
4009 if (path.wide)
4010 result = RemoveDirectoryW(path.wide);
4011 else
4012 result = RemoveDirectoryA(path.narrow);
4013 result = !result; /* Windows, success=1, UNIX, success=0 */
4014#else
4015#ifdef HAVE_UNLINKAT
4016 if (dir_fd != DEFAULT_DIR_FD)
4017 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
4018 else
4019#endif
4020 result = rmdir(path.narrow);
4021#endif
4022 Py_END_ALLOW_THREADS
4023
4024 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004025 return_value = path_error(&path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004026 goto exit;
4027 }
4028
4029 return_value = Py_None;
4030 Py_INCREF(Py_None);
4031
4032exit:
4033 path_cleanup(&path);
4034 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004035}
4036
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004037
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004038#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004039PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004040"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004041Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004042
Barry Warsaw53699e91996-12-10 23:23:01 +00004043static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004044posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004045{
Victor Stinner8c62be82010-05-06 00:08:46 +00004046 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004047#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004048 wchar_t *command;
4049 if (!PyArg_ParseTuple(args, "u:system", &command))
4050 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004051
Victor Stinner8c62be82010-05-06 00:08:46 +00004052 Py_BEGIN_ALLOW_THREADS
4053 sts = _wsystem(command);
4054 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004055#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004056 PyObject *command_obj;
4057 char *command;
4058 if (!PyArg_ParseTuple(args, "O&:system",
4059 PyUnicode_FSConverter, &command_obj))
4060 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004061
Victor Stinner8c62be82010-05-06 00:08:46 +00004062 command = PyBytes_AsString(command_obj);
4063 Py_BEGIN_ALLOW_THREADS
4064 sts = system(command);
4065 Py_END_ALLOW_THREADS
4066 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004067#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004068 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004069}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004070#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004071
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004072
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004073PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004074"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004075Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004076
Barry Warsaw53699e91996-12-10 23:23:01 +00004077static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004078posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004079{
Victor Stinner8c62be82010-05-06 00:08:46 +00004080 int i;
4081 if (!PyArg_ParseTuple(args, "i:umask", &i))
4082 return NULL;
4083 i = (int)umask(i);
4084 if (i < 0)
4085 return posix_error();
4086 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004087}
4088
Brian Curtind40e6f72010-07-08 21:39:08 +00004089#ifdef MS_WINDOWS
4090
4091/* override the default DeleteFileW behavior so that directory
4092symlinks can be removed with this function, the same as with
4093Unix symlinks */
4094BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4095{
4096 WIN32_FILE_ATTRIBUTE_DATA info;
4097 WIN32_FIND_DATAW find_data;
4098 HANDLE find_data_handle;
4099 int is_directory = 0;
4100 int is_link = 0;
4101
4102 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4103 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004104
Brian Curtind40e6f72010-07-08 21:39:08 +00004105 /* Get WIN32_FIND_DATA structure for the path to determine if
4106 it is a symlink */
4107 if(is_directory &&
4108 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4109 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4110
4111 if(find_data_handle != INVALID_HANDLE_VALUE) {
4112 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4113 FindClose(find_data_handle);
4114 }
4115 }
4116 }
4117
4118 if (is_directory && is_link)
4119 return RemoveDirectoryW(lpFileName);
4120
4121 return DeleteFileW(lpFileName);
4122}
4123#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004124
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004125PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004126"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004127Remove a file (same as remove()).\n\
4128\n\
4129If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4130 and path should be relative; path will then be relative to that directory.\n\
4131dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004132 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004133
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004134PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004135"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004136Remove a file (same as unlink()).\n\
4137\n\
4138If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4139 and path should be relative; path will then be relative to that directory.\n\
4140dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004141 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004142
Barry Warsaw53699e91996-12-10 23:23:01 +00004143static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004144posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004145{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004146 path_t path;
4147 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004148 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004149 int result;
4150 PyObject *return_value = NULL;
4151
4152 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004153 path.function_name = "unlink";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004154 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004155 path_converter, &path,
4156#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004157 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004158#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004159 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004160#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004161 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004162 return NULL;
4163
4164 Py_BEGIN_ALLOW_THREADS
4165#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004166 if (path.wide)
4167 result = Py_DeleteFileW(path.wide);
4168 else
4169 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004170 result = !result; /* Windows, success=1, UNIX, success=0 */
4171#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004172#ifdef HAVE_UNLINKAT
4173 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004174 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004175 else
4176#endif /* HAVE_UNLINKAT */
4177 result = unlink(path.narrow);
4178#endif
4179 Py_END_ALLOW_THREADS
4180
4181 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004182 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004183 goto exit;
4184 }
4185
4186 return_value = Py_None;
4187 Py_INCREF(Py_None);
4188
4189exit:
4190 path_cleanup(&path);
4191 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004192}
4193
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004194
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004195PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004196"uname() -> uname_result\n\n\
4197Return an object identifying the current operating system.\n\
4198The object behaves like a named tuple with the following fields:\n\
4199 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004200
Larry Hastings605a62d2012-06-24 04:33:36 -07004201static PyStructSequence_Field uname_result_fields[] = {
4202 {"sysname", "operating system name"},
4203 {"nodename", "name of machine on network (implementation-defined)"},
4204 {"release", "operating system release"},
4205 {"version", "operating system version"},
4206 {"machine", "hardware identifier"},
4207 {NULL}
4208};
4209
4210PyDoc_STRVAR(uname_result__doc__,
4211"uname_result: Result from os.uname().\n\n\
4212This object may be accessed either as a tuple of\n\
4213 (sysname, nodename, release, version, machine),\n\
4214or via the attributes sysname, nodename, release, version, and machine.\n\
4215\n\
4216See os.uname for more information.");
4217
4218static PyStructSequence_Desc uname_result_desc = {
4219 "uname_result", /* name */
4220 uname_result__doc__, /* doc */
4221 uname_result_fields,
4222 5
4223};
4224
4225static PyTypeObject UnameResultType;
4226
4227
4228#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004229static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004230posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004231{
Victor Stinner8c62be82010-05-06 00:08:46 +00004232 struct utsname u;
4233 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004234 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004235
Victor Stinner8c62be82010-05-06 00:08:46 +00004236 Py_BEGIN_ALLOW_THREADS
4237 res = uname(&u);
4238 Py_END_ALLOW_THREADS
4239 if (res < 0)
4240 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004241
4242 value = PyStructSequence_New(&UnameResultType);
4243 if (value == NULL)
4244 return NULL;
4245
4246#define SET(i, field) \
4247 { \
4248 PyObject *o = PyUnicode_DecodeASCII(field, strlen(field), NULL); \
4249 if (!o) { \
4250 Py_DECREF(value); \
4251 return NULL; \
4252 } \
4253 PyStructSequence_SET_ITEM(value, i, o); \
4254 } \
4255
4256 SET(0, u.sysname);
4257 SET(1, u.nodename);
4258 SET(2, u.release);
4259 SET(3, u.version);
4260 SET(4, u.machine);
4261
4262#undef SET
4263
4264 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004265}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004266#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004267
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004268
Larry Hastings9cf065c2012-06-22 16:30:09 -07004269PyDoc_STRVAR(posix_utime__doc__,
4270"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4271Set the access and modified time of path.\n\
4272\n\
4273path may always be specified as a string.\n\
4274On some platforms, path may also be specified as an open file descriptor.\n\
4275 If this functionality is unavailable, using it raises an exception.\n\
4276\n\
4277If times is not None, it must be a tuple (atime, mtime);\n\
4278 atime and mtime should be expressed as float seconds since the epoch.\n\
4279If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4280 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4281 since the epoch.\n\
4282If both times and ns are None, utime uses the current time.\n\
4283Specifying tuples for both times and ns is an error.\n\
4284\n\
4285If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4286 and path should be relative; path will then be relative to that directory.\n\
4287If follow_symlinks is False, and the last element of the path is a symbolic\n\
4288 link, utime will modify the symbolic link itself instead of the file the\n\
4289 link points to.\n\
4290It is an error to use dir_fd or follow_symlinks when specifying path\n\
4291 as an open file descriptor.\n\
4292dir_fd and follow_symlinks may not be available on your platform.\n\
4293 If they are unavailable, using them will raise a NotImplementedError.");
4294
4295typedef struct {
4296 int now;
4297 time_t atime_s;
4298 long atime_ns;
4299 time_t mtime_s;
4300 long mtime_ns;
4301} utime_t;
4302
4303/*
4304 * these macros assume that "utime" is a pointer to a utime_t
4305 * they also intentionally leak the declaration of a pointer named "time"
4306 */
4307#define UTIME_TO_TIMESPEC \
4308 struct timespec ts[2]; \
4309 struct timespec *time; \
4310 if (utime->now) \
4311 time = NULL; \
4312 else { \
4313 ts[0].tv_sec = utime->atime_s; \
4314 ts[0].tv_nsec = utime->atime_ns; \
4315 ts[1].tv_sec = utime->mtime_s; \
4316 ts[1].tv_nsec = utime->mtime_ns; \
4317 time = ts; \
4318 } \
4319
4320#define UTIME_TO_TIMEVAL \
4321 struct timeval tv[2]; \
4322 struct timeval *time; \
4323 if (utime->now) \
4324 time = NULL; \
4325 else { \
4326 tv[0].tv_sec = utime->atime_s; \
4327 tv[0].tv_usec = utime->atime_ns / 1000; \
4328 tv[1].tv_sec = utime->mtime_s; \
4329 tv[1].tv_usec = utime->mtime_ns / 1000; \
4330 time = tv; \
4331 } \
4332
4333#define UTIME_TO_UTIMBUF \
4334 struct utimbuf u[2]; \
4335 struct utimbuf *time; \
4336 if (utime->now) \
4337 time = NULL; \
4338 else { \
4339 u.actime = utime->atime_s; \
4340 u.modtime = utime->mtime_s; \
4341 time = u; \
4342 }
4343
4344#define UTIME_TO_TIME_T \
4345 time_t timet[2]; \
4346 struct timet time; \
4347 if (utime->now) \
4348 time = NULL; \
4349 else { \
4350 timet[0] = utime->atime_s; \
4351 timet[1] = utime->mtime_s; \
4352 time = &timet; \
4353 } \
4354
4355
4356#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4357
4358#if UTIME_HAVE_DIR_FD
4359
4360static int
4361utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4362{
4363#ifdef HAVE_UTIMENSAT
4364 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4365 UTIME_TO_TIMESPEC;
4366 return utimensat(dir_fd, path, time, flags);
4367#elif defined(HAVE_FUTIMESAT)
4368 UTIME_TO_TIMEVAL;
4369 /*
4370 * follow_symlinks will never be false here;
4371 * we only allow !follow_symlinks and dir_fd together
4372 * if we have utimensat()
4373 */
4374 assert(follow_symlinks);
4375 return futimesat(dir_fd, path, time);
4376#endif
4377}
4378
4379#endif
4380
4381#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4382
4383#if UTIME_HAVE_FD
4384
4385static int
4386utime_fd(utime_t *utime, int fd)
4387{
4388#ifdef HAVE_FUTIMENS
4389 UTIME_TO_TIMESPEC;
4390 return futimens(fd, time);
4391#else
4392 UTIME_TO_TIMEVAL;
4393 return futimes(fd, time);
4394#endif
4395}
4396
4397#endif
4398
4399
4400#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4401 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4402
4403#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4404
4405static int
4406utime_nofollow_symlinks(utime_t *utime, char *path)
4407{
4408#ifdef HAVE_UTIMENSAT
4409 UTIME_TO_TIMESPEC;
4410 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4411#else
4412 UTIME_TO_TIMEVAL;
4413 return lutimes(path, time);
4414#endif
4415}
4416
4417#endif
4418
4419#ifndef MS_WINDOWS
4420
4421static int
4422utime_default(utime_t *utime, char *path)
4423{
4424#ifdef HAVE_UTIMENSAT
4425 UTIME_TO_TIMESPEC;
4426 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4427#elif defined(HAVE_UTIMES)
4428 UTIME_TO_TIMEVAL;
4429 return utimes(path, time);
4430#elif defined(HAVE_UTIME_H)
4431 UTIME_TO_UTIMBUF;
4432 return utime(path, time);
4433#else
4434 UTIME_TO_TIME_T;
4435 return utime(path, time);
4436#endif
4437}
4438
4439#endif
4440
Larry Hastings76ad59b2012-05-03 00:30:07 -07004441static int
4442split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4443{
4444 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004445 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004446 divmod = PyNumber_Divmod(py_long, billion);
4447 if (!divmod)
4448 goto exit;
4449 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4450 if ((*s == -1) && PyErr_Occurred())
4451 goto exit;
4452 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004453 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004454 goto exit;
4455
4456 result = 1;
4457exit:
4458 Py_XDECREF(divmod);
4459 return result;
4460}
4461
Larry Hastings9cf065c2012-06-22 16:30:09 -07004462static PyObject *
4463posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004464{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004465 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004466 PyObject *times = NULL;
4467 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004468 int dir_fd = DEFAULT_DIR_FD;
4469 int follow_symlinks = 1;
4470 char *keywords[] = {"path", "times", "ns", "dir_fd",
4471 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004472
Larry Hastings9cf065c2012-06-22 16:30:09 -07004473 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004474
Larry Hastings9cf065c2012-06-22 16:30:09 -07004475#ifdef MS_WINDOWS
4476 HANDLE hFile;
4477 FILETIME atime, mtime;
4478#else
4479 int result;
4480#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004481
Larry Hastings9cf065c2012-06-22 16:30:09 -07004482 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004483
Larry Hastings9cf065c2012-06-22 16:30:09 -07004484 memset(&path, 0, sizeof(path));
Victor Stinnerb024e842012-10-31 22:24:06 +01004485 path.function_name = "utime";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004486#if UTIME_HAVE_FD
4487 path.allow_fd = 1;
4488#endif
4489 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4490 "O&|O$OO&p:utime", keywords,
4491 path_converter, &path,
4492 &times, &ns,
4493#if UTIME_HAVE_DIR_FD
4494 dir_fd_converter, &dir_fd,
4495#else
4496 dir_fd_unavailable, &dir_fd,
4497#endif
4498 &follow_symlinks
4499 ))
4500 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004501
Larry Hastings9cf065c2012-06-22 16:30:09 -07004502 if (times && (times != Py_None) && ns) {
4503 PyErr_SetString(PyExc_ValueError,
4504 "utime: you may specify either 'times'"
4505 " or 'ns' but not both");
4506 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004507 }
4508
4509 if (times && (times != Py_None)) {
4510 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004511 PyErr_SetString(PyExc_TypeError,
4512 "utime: 'times' must be either"
4513 " a tuple of two ints or None");
4514 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004515 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004516 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004517 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004518 &utime.atime_s, &utime.atime_ns) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004519 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004520 &utime.mtime_s, &utime.mtime_ns) == -1) {
4521 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004522 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004523 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004524 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004525 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004526 PyErr_SetString(PyExc_TypeError,
4527 "utime: 'ns' must be a tuple of two ints");
4528 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004529 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004530 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004531 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004532 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004533 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004534 &utime.mtime_s, &utime.mtime_ns)) {
4535 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004536 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004537 }
4538 else {
4539 /* times and ns are both None/unspecified. use "now". */
4540 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004541 }
4542
Larry Hastings9cf065c2012-06-22 16:30:09 -07004543#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4544 if (follow_symlinks_specified("utime", follow_symlinks))
4545 goto exit;
4546#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004547
Larry Hastings9cf065c2012-06-22 16:30:09 -07004548 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4549 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4550 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4551 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004552
Larry Hastings9cf065c2012-06-22 16:30:09 -07004553#if !defined(HAVE_UTIMENSAT)
4554 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004555 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004556 "utime: cannot use dir_fd and follow_symlinks "
4557 "together on this platform");
4558 goto exit;
4559 }
4560#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004561
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004562#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004563 Py_BEGIN_ALLOW_THREADS
4564 if (path.wide)
4565 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004566 NULL, OPEN_EXISTING,
4567 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004568 else
4569 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004570 NULL, OPEN_EXISTING,
4571 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004572 Py_END_ALLOW_THREADS
4573 if (hFile == INVALID_HANDLE_VALUE) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004574 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004575 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004576 }
4577
Larry Hastings9cf065c2012-06-22 16:30:09 -07004578 if (utime.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004579 SYSTEMTIME now;
4580 GetSystemTime(&now);
4581 if (!SystemTimeToFileTime(&now, &mtime) ||
4582 !SystemTimeToFileTime(&now, &atime)) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004583 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004584 goto exit;
Stefan Krah0e803b32010-11-26 16:16:47 +00004585 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004586 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004587 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004588 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4589 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004590 }
4591 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4592 /* Avoid putting the file name into the error here,
4593 as that may confuse the user into believing that
4594 something is wrong with the file, when it also
4595 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004596 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004597 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004598 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004599#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004600 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004601
Larry Hastings9cf065c2012-06-22 16:30:09 -07004602#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4603 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4604 result = utime_nofollow_symlinks(&utime, path.narrow);
4605 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004606#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004607
4608#if UTIME_HAVE_DIR_FD
4609 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4610 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4611 else
4612#endif
4613
4614#if UTIME_HAVE_FD
4615 if (path.fd != -1)
4616 result = utime_fd(&utime, path.fd);
4617 else
4618#endif
4619
4620 result = utime_default(&utime, path.narrow);
4621
4622 Py_END_ALLOW_THREADS
4623
4624 if (result < 0) {
4625 /* see previous comment about not putting filename in error here */
4626 return_value = posix_error();
4627 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004628 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004629
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004630#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004631
4632 Py_INCREF(Py_None);
4633 return_value = Py_None;
4634
4635exit:
4636 path_cleanup(&path);
4637#ifdef MS_WINDOWS
4638 if (hFile != INVALID_HANDLE_VALUE)
4639 CloseHandle(hFile);
4640#endif
4641 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004642}
4643
Guido van Rossum3b066191991-06-04 19:40:25 +00004644/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004645
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004646PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004647"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004648Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004649
Barry Warsaw53699e91996-12-10 23:23:01 +00004650static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004651posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004652{
Victor Stinner8c62be82010-05-06 00:08:46 +00004653 int sts;
4654 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
4655 return NULL;
4656 _exit(sts);
4657 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004658}
4659
Martin v. Löwis114619e2002-10-07 06:44:21 +00004660#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4661static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004662free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004663{
Victor Stinner8c62be82010-05-06 00:08:46 +00004664 Py_ssize_t i;
4665 for (i = 0; i < count; i++)
4666 PyMem_Free(array[i]);
4667 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004668}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004669
Antoine Pitrou69f71142009-05-24 21:25:49 +00004670static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004671int fsconvert_strdup(PyObject *o, char**out)
4672{
Victor Stinner8c62be82010-05-06 00:08:46 +00004673 PyObject *bytes;
4674 Py_ssize_t size;
4675 if (!PyUnicode_FSConverter(o, &bytes))
4676 return 0;
4677 size = PyBytes_GET_SIZE(bytes);
4678 *out = PyMem_Malloc(size+1);
4679 if (!*out)
4680 return 0;
4681 memcpy(*out, PyBytes_AsString(bytes), size+1);
4682 Py_DECREF(bytes);
4683 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004684}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004685#endif
4686
Ross Lagerwall7807c352011-03-17 20:20:30 +02004687#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004688static char**
4689parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4690{
Victor Stinner8c62be82010-05-06 00:08:46 +00004691 char **envlist;
4692 Py_ssize_t i, pos, envc;
4693 PyObject *keys=NULL, *vals=NULL;
4694 PyObject *key, *val, *key2, *val2;
4695 char *p, *k, *v;
4696 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004697
Victor Stinner8c62be82010-05-06 00:08:46 +00004698 i = PyMapping_Size(env);
4699 if (i < 0)
4700 return NULL;
4701 envlist = PyMem_NEW(char *, i + 1);
4702 if (envlist == NULL) {
4703 PyErr_NoMemory();
4704 return NULL;
4705 }
4706 envc = 0;
4707 keys = PyMapping_Keys(env);
4708 vals = PyMapping_Values(env);
4709 if (!keys || !vals)
4710 goto error;
4711 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4712 PyErr_Format(PyExc_TypeError,
4713 "env.keys() or env.values() is not a list");
4714 goto error;
4715 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004716
Victor Stinner8c62be82010-05-06 00:08:46 +00004717 for (pos = 0; pos < i; pos++) {
4718 key = PyList_GetItem(keys, pos);
4719 val = PyList_GetItem(vals, pos);
4720 if (!key || !val)
4721 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004722
Victor Stinner8c62be82010-05-06 00:08:46 +00004723 if (PyUnicode_FSConverter(key, &key2) == 0)
4724 goto error;
4725 if (PyUnicode_FSConverter(val, &val2) == 0) {
4726 Py_DECREF(key2);
4727 goto error;
4728 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004729
Victor Stinner8c62be82010-05-06 00:08:46 +00004730 k = PyBytes_AsString(key2);
4731 v = PyBytes_AsString(val2);
4732 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004733
Victor Stinner8c62be82010-05-06 00:08:46 +00004734 p = PyMem_NEW(char, len);
4735 if (p == NULL) {
4736 PyErr_NoMemory();
4737 Py_DECREF(key2);
4738 Py_DECREF(val2);
4739 goto error;
4740 }
4741 PyOS_snprintf(p, len, "%s=%s", k, v);
4742 envlist[envc++] = p;
4743 Py_DECREF(key2);
4744 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00004745 }
4746 Py_DECREF(vals);
4747 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004748
Victor Stinner8c62be82010-05-06 00:08:46 +00004749 envlist[envc] = 0;
4750 *envc_ptr = envc;
4751 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004752
4753error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004754 Py_XDECREF(keys);
4755 Py_XDECREF(vals);
4756 while (--envc >= 0)
4757 PyMem_DEL(envlist[envc]);
4758 PyMem_DEL(envlist);
4759 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004760}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004761
Ross Lagerwall7807c352011-03-17 20:20:30 +02004762static char**
4763parse_arglist(PyObject* argv, Py_ssize_t *argc)
4764{
4765 int i;
4766 char **argvlist = PyMem_NEW(char *, *argc+1);
4767 if (argvlist == NULL) {
4768 PyErr_NoMemory();
4769 return NULL;
4770 }
4771 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004772 PyObject* item = PySequence_ITEM(argv, i);
4773 if (item == NULL)
4774 goto fail;
4775 if (!fsconvert_strdup(item, &argvlist[i])) {
4776 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004777 goto fail;
4778 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004779 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004780 }
4781 argvlist[*argc] = NULL;
4782 return argvlist;
4783fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004784 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004785 free_string_array(argvlist, *argc);
4786 return NULL;
4787}
4788#endif
4789
4790#ifdef HAVE_EXECV
4791PyDoc_STRVAR(posix_execv__doc__,
4792"execv(path, args)\n\n\
4793Execute an executable path with arguments, replacing current process.\n\
4794\n\
4795 path: path of executable file\n\
4796 args: tuple or list of strings");
4797
4798static PyObject *
4799posix_execv(PyObject *self, PyObject *args)
4800{
4801 PyObject *opath;
4802 char *path;
4803 PyObject *argv;
4804 char **argvlist;
4805 Py_ssize_t argc;
4806
4807 /* execv has two arguments: (path, argv), where
4808 argv is a list or tuple of strings. */
4809
4810 if (!PyArg_ParseTuple(args, "O&O:execv",
4811 PyUnicode_FSConverter,
4812 &opath, &argv))
4813 return NULL;
4814 path = PyBytes_AsString(opath);
4815 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4816 PyErr_SetString(PyExc_TypeError,
4817 "execv() arg 2 must be a tuple or list");
4818 Py_DECREF(opath);
4819 return NULL;
4820 }
4821 argc = PySequence_Size(argv);
4822 if (argc < 1) {
4823 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
4824 Py_DECREF(opath);
4825 return NULL;
4826 }
4827
4828 argvlist = parse_arglist(argv, &argc);
4829 if (argvlist == NULL) {
4830 Py_DECREF(opath);
4831 return NULL;
4832 }
4833
4834 execv(path, argvlist);
4835
4836 /* If we get here it's definitely an error */
4837
4838 free_string_array(argvlist, argc);
4839 Py_DECREF(opath);
4840 return posix_error();
4841}
4842
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004843PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004844"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004845Execute a path with arguments and environment, replacing current process.\n\
4846\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004847 path: path of executable file\n\
4848 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004849 env: dictionary of strings mapping to strings\n\
4850\n\
4851On some platforms, you may specify an open file descriptor for path;\n\
4852 execve will execute the program the file descriptor is open to.\n\
4853 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004854
Barry Warsaw53699e91996-12-10 23:23:01 +00004855static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004856posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004857{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004858 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004859 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004860 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004861 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004862 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004863 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004864
Victor Stinner8c62be82010-05-06 00:08:46 +00004865 /* execve has three arguments: (path, argv, env), where
4866 argv is a list or tuple of strings and env is a dictionary
4867 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004868
Larry Hastings9cf065c2012-06-22 16:30:09 -07004869 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004870 path.function_name = "execve";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004871#ifdef HAVE_FEXECVE
4872 path.allow_fd = 1;
4873#endif
4874 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
4875 path_converter, &path,
4876 &argv, &env
4877 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00004878 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004879
Ross Lagerwall7807c352011-03-17 20:20:30 +02004880 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004881 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004882 "execve: argv must be a tuple or list");
4883 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004884 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004885 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00004886 if (!PyMapping_Check(env)) {
4887 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004888 "execve: environment must be a mapping object");
4889 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004890 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004891
Ross Lagerwall7807c352011-03-17 20:20:30 +02004892 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004893 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004894 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004895 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004896
Victor Stinner8c62be82010-05-06 00:08:46 +00004897 envlist = parse_envlist(env, &envc);
4898 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02004899 goto fail;
4900
Larry Hastings9cf065c2012-06-22 16:30:09 -07004901#ifdef HAVE_FEXECVE
4902 if (path.fd > -1)
4903 fexecve(path.fd, argvlist, envlist);
4904 else
4905#endif
4906 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004907
4908 /* If we get here it's definitely an error */
4909
Victor Stinner292c8352012-10-30 02:17:38 +01004910 path_error(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004911
4912 while (--envc >= 0)
4913 PyMem_DEL(envlist[envc]);
4914 PyMem_DEL(envlist);
4915 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004916 if (argvlist)
4917 free_string_array(argvlist, argc);
4918 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004919 return NULL;
4920}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004921#endif /* HAVE_EXECV */
4922
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004923
Guido van Rossuma1065681999-01-25 23:20:23 +00004924#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004925PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004926"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004927Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004928\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004929 mode: mode of process creation\n\
4930 path: path of executable file\n\
4931 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004932
4933static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004934posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004935{
Victor Stinner8c62be82010-05-06 00:08:46 +00004936 PyObject *opath;
4937 char *path;
4938 PyObject *argv;
4939 char **argvlist;
4940 int mode, i;
4941 Py_ssize_t argc;
4942 Py_intptr_t spawnval;
4943 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00004944
Victor Stinner8c62be82010-05-06 00:08:46 +00004945 /* spawnv has three arguments: (mode, path, argv), where
4946 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004947
Victor Stinner8c62be82010-05-06 00:08:46 +00004948 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
4949 PyUnicode_FSConverter,
4950 &opath, &argv))
4951 return NULL;
4952 path = PyBytes_AsString(opath);
4953 if (PyList_Check(argv)) {
4954 argc = PyList_Size(argv);
4955 getitem = PyList_GetItem;
4956 }
4957 else if (PyTuple_Check(argv)) {
4958 argc = PyTuple_Size(argv);
4959 getitem = PyTuple_GetItem;
4960 }
4961 else {
4962 PyErr_SetString(PyExc_TypeError,
4963 "spawnv() arg 2 must be a tuple or list");
4964 Py_DECREF(opath);
4965 return NULL;
4966 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004967
Victor Stinner8c62be82010-05-06 00:08:46 +00004968 argvlist = PyMem_NEW(char *, argc+1);
4969 if (argvlist == NULL) {
4970 Py_DECREF(opath);
4971 return PyErr_NoMemory();
4972 }
4973 for (i = 0; i < argc; i++) {
4974 if (!fsconvert_strdup((*getitem)(argv, i),
4975 &argvlist[i])) {
4976 free_string_array(argvlist, i);
4977 PyErr_SetString(
4978 PyExc_TypeError,
4979 "spawnv() arg 2 must contain only strings");
4980 Py_DECREF(opath);
4981 return NULL;
4982 }
4983 }
4984 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004985
Victor Stinner8c62be82010-05-06 00:08:46 +00004986 if (mode == _OLD_P_OVERLAY)
4987 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00004988
Victor Stinner8c62be82010-05-06 00:08:46 +00004989 Py_BEGIN_ALLOW_THREADS
4990 spawnval = _spawnv(mode, path, argvlist);
4991 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00004992
Victor Stinner8c62be82010-05-06 00:08:46 +00004993 free_string_array(argvlist, argc);
4994 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00004995
Victor Stinner8c62be82010-05-06 00:08:46 +00004996 if (spawnval == -1)
4997 return posix_error();
4998 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004999#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005000 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005001#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005002 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005003#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005004}
5005
5006
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005007PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005008"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005009Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005010\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005011 mode: mode of process creation\n\
5012 path: path of executable file\n\
5013 args: tuple or list of arguments\n\
5014 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005015
5016static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005017posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005018{
Victor Stinner8c62be82010-05-06 00:08:46 +00005019 PyObject *opath;
5020 char *path;
5021 PyObject *argv, *env;
5022 char **argvlist;
5023 char **envlist;
5024 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005025 int mode;
5026 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005027 Py_intptr_t spawnval;
5028 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5029 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005030
Victor Stinner8c62be82010-05-06 00:08:46 +00005031 /* spawnve has four arguments: (mode, path, argv, env), where
5032 argv is a list or tuple of strings and env is a dictionary
5033 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005034
Victor Stinner8c62be82010-05-06 00:08:46 +00005035 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5036 PyUnicode_FSConverter,
5037 &opath, &argv, &env))
5038 return NULL;
5039 path = PyBytes_AsString(opath);
5040 if (PyList_Check(argv)) {
5041 argc = PyList_Size(argv);
5042 getitem = PyList_GetItem;
5043 }
5044 else if (PyTuple_Check(argv)) {
5045 argc = PyTuple_Size(argv);
5046 getitem = PyTuple_GetItem;
5047 }
5048 else {
5049 PyErr_SetString(PyExc_TypeError,
5050 "spawnve() arg 2 must be a tuple or list");
5051 goto fail_0;
5052 }
5053 if (!PyMapping_Check(env)) {
5054 PyErr_SetString(PyExc_TypeError,
5055 "spawnve() arg 3 must be a mapping object");
5056 goto fail_0;
5057 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005058
Victor Stinner8c62be82010-05-06 00:08:46 +00005059 argvlist = PyMem_NEW(char *, argc+1);
5060 if (argvlist == NULL) {
5061 PyErr_NoMemory();
5062 goto fail_0;
5063 }
5064 for (i = 0; i < argc; i++) {
5065 if (!fsconvert_strdup((*getitem)(argv, i),
5066 &argvlist[i]))
5067 {
5068 lastarg = i;
5069 goto fail_1;
5070 }
5071 }
5072 lastarg = argc;
5073 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005074
Victor Stinner8c62be82010-05-06 00:08:46 +00005075 envlist = parse_envlist(env, &envc);
5076 if (envlist == NULL)
5077 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005078
Victor Stinner8c62be82010-05-06 00:08:46 +00005079 if (mode == _OLD_P_OVERLAY)
5080 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005081
Victor Stinner8c62be82010-05-06 00:08:46 +00005082 Py_BEGIN_ALLOW_THREADS
5083 spawnval = _spawnve(mode, path, argvlist, envlist);
5084 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005085
Victor Stinner8c62be82010-05-06 00:08:46 +00005086 if (spawnval == -1)
5087 (void) posix_error();
5088 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005089#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005090 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005091#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005092 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005093#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005094
Victor Stinner8c62be82010-05-06 00:08:46 +00005095 while (--envc >= 0)
5096 PyMem_DEL(envlist[envc]);
5097 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005098 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005099 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005100 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005101 Py_DECREF(opath);
5102 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005103}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005104
Guido van Rossuma1065681999-01-25 23:20:23 +00005105#endif /* HAVE_SPAWNV */
5106
5107
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005108#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005109PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005110"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005111Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5112\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005113Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005114
5115static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005116posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005117{
Victor Stinner8c62be82010-05-06 00:08:46 +00005118 pid_t pid;
5119 int result = 0;
5120 _PyImport_AcquireLock();
5121 pid = fork1();
5122 if (pid == 0) {
5123 /* child: this clobbers and resets the import lock. */
5124 PyOS_AfterFork();
5125 } else {
5126 /* parent: release the import lock. */
5127 result = _PyImport_ReleaseLock();
5128 }
5129 if (pid == -1)
5130 return posix_error();
5131 if (result < 0) {
5132 /* Don't clobber the OSError if the fork failed. */
5133 PyErr_SetString(PyExc_RuntimeError,
5134 "not holding the import lock");
5135 return NULL;
5136 }
5137 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005138}
5139#endif
5140
5141
Guido van Rossumad0ee831995-03-01 10:34:45 +00005142#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005143PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005144"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005145Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005146Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005147
Barry Warsaw53699e91996-12-10 23:23:01 +00005148static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005149posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005150{
Victor Stinner8c62be82010-05-06 00:08:46 +00005151 pid_t pid;
5152 int result = 0;
5153 _PyImport_AcquireLock();
5154 pid = fork();
5155 if (pid == 0) {
5156 /* child: this clobbers and resets the import lock. */
5157 PyOS_AfterFork();
5158 } else {
5159 /* parent: release the import lock. */
5160 result = _PyImport_ReleaseLock();
5161 }
5162 if (pid == -1)
5163 return posix_error();
5164 if (result < 0) {
5165 /* Don't clobber the OSError if the fork failed. */
5166 PyErr_SetString(PyExc_RuntimeError,
5167 "not holding the import lock");
5168 return NULL;
5169 }
5170 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005171}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005172#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005173
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005174#ifdef HAVE_SCHED_H
5175
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005176#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5177
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005178PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5179"sched_get_priority_max(policy)\n\n\
5180Get the maximum scheduling priority for *policy*.");
5181
5182static PyObject *
5183posix_sched_get_priority_max(PyObject *self, PyObject *args)
5184{
5185 int policy, max;
5186
5187 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5188 return NULL;
5189 max = sched_get_priority_max(policy);
5190 if (max < 0)
5191 return posix_error();
5192 return PyLong_FromLong(max);
5193}
5194
5195PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5196"sched_get_priority_min(policy)\n\n\
5197Get the minimum scheduling priority for *policy*.");
5198
5199static PyObject *
5200posix_sched_get_priority_min(PyObject *self, PyObject *args)
5201{
5202 int policy, min;
5203
5204 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5205 return NULL;
5206 min = sched_get_priority_min(policy);
5207 if (min < 0)
5208 return posix_error();
5209 return PyLong_FromLong(min);
5210}
5211
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005212#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5213
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005214#ifdef HAVE_SCHED_SETSCHEDULER
5215
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005216PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5217"sched_getscheduler(pid)\n\n\
5218Get the scheduling policy for the process with a PID of *pid*.\n\
5219Passing a PID of 0 returns the scheduling policy for the calling process.");
5220
5221static PyObject *
5222posix_sched_getscheduler(PyObject *self, PyObject *args)
5223{
5224 pid_t pid;
5225 int policy;
5226
5227 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5228 return NULL;
5229 policy = sched_getscheduler(pid);
5230 if (policy < 0)
5231 return posix_error();
5232 return PyLong_FromLong(policy);
5233}
5234
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005235#endif
5236
5237#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5238
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005239static PyObject *
5240sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5241{
5242 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005243 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005244
5245 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5246 return NULL;
5247 res = PyStructSequence_New(type);
5248 if (!res)
5249 return NULL;
5250 Py_INCREF(priority);
5251 PyStructSequence_SET_ITEM(res, 0, priority);
5252 return res;
5253}
5254
5255PyDoc_STRVAR(sched_param__doc__,
5256"sched_param(sched_priority): A scheduling parameter.\n\n\
5257Current has only one field: sched_priority");
5258
5259static PyStructSequence_Field sched_param_fields[] = {
5260 {"sched_priority", "the scheduling priority"},
5261 {0}
5262};
5263
5264static PyStructSequence_Desc sched_param_desc = {
5265 "sched_param", /* name */
5266 sched_param__doc__, /* doc */
5267 sched_param_fields,
5268 1
5269};
5270
5271static int
5272convert_sched_param(PyObject *param, struct sched_param *res)
5273{
5274 long priority;
5275
5276 if (Py_TYPE(param) != &SchedParamType) {
5277 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5278 return 0;
5279 }
5280 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5281 if (priority == -1 && PyErr_Occurred())
5282 return 0;
5283 if (priority > INT_MAX || priority < INT_MIN) {
5284 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5285 return 0;
5286 }
5287 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5288 return 1;
5289}
5290
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005291#endif
5292
5293#ifdef HAVE_SCHED_SETSCHEDULER
5294
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005295PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5296"sched_setscheduler(pid, policy, param)\n\n\
5297Set the scheduling policy, *policy*, for *pid*.\n\
5298If *pid* is 0, the calling process is changed.\n\
5299*param* is an instance of sched_param.");
5300
5301static PyObject *
5302posix_sched_setscheduler(PyObject *self, PyObject *args)
5303{
5304 pid_t pid;
5305 int policy;
5306 struct sched_param param;
5307
5308 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5309 &pid, &policy, &convert_sched_param, &param))
5310 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005311
5312 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005313 ** sched_setscheduler() returns 0 in Linux, but the previous
5314 ** scheduling policy under Solaris/Illumos, and others.
5315 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005316 */
5317 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005318 return posix_error();
5319 Py_RETURN_NONE;
5320}
5321
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005322#endif
5323
5324#ifdef HAVE_SCHED_SETPARAM
5325
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005326PyDoc_STRVAR(posix_sched_getparam__doc__,
5327"sched_getparam(pid) -> sched_param\n\n\
5328Returns scheduling parameters for the process with *pid* as an instance of the\n\
5329sched_param class. A PID of 0 means the calling process.");
5330
5331static PyObject *
5332posix_sched_getparam(PyObject *self, PyObject *args)
5333{
5334 pid_t pid;
5335 struct sched_param param;
5336 PyObject *res, *priority;
5337
5338 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5339 return NULL;
5340 if (sched_getparam(pid, &param))
5341 return posix_error();
5342 res = PyStructSequence_New(&SchedParamType);
5343 if (!res)
5344 return NULL;
5345 priority = PyLong_FromLong(param.sched_priority);
5346 if (!priority) {
5347 Py_DECREF(res);
5348 return NULL;
5349 }
5350 PyStructSequence_SET_ITEM(res, 0, priority);
5351 return res;
5352}
5353
5354PyDoc_STRVAR(posix_sched_setparam__doc__,
5355"sched_setparam(pid, param)\n\n\
5356Set scheduling parameters for a process with PID *pid*.\n\
5357A PID of 0 means the calling process.");
5358
5359static PyObject *
5360posix_sched_setparam(PyObject *self, PyObject *args)
5361{
5362 pid_t pid;
5363 struct sched_param param;
5364
5365 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5366 &pid, &convert_sched_param, &param))
5367 return NULL;
5368 if (sched_setparam(pid, &param))
5369 return posix_error();
5370 Py_RETURN_NONE;
5371}
5372
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005373#endif
5374
5375#ifdef HAVE_SCHED_RR_GET_INTERVAL
5376
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005377PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5378"sched_rr_get_interval(pid) -> float\n\n\
5379Return the round-robin quantum for the process with PID *pid* in seconds.");
5380
5381static PyObject *
5382posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5383{
5384 pid_t pid;
5385 struct timespec interval;
5386
5387 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5388 return NULL;
5389 if (sched_rr_get_interval(pid, &interval))
5390 return posix_error();
5391 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5392}
5393
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005394#endif
5395
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005396PyDoc_STRVAR(posix_sched_yield__doc__,
5397"sched_yield()\n\n\
5398Voluntarily relinquish the CPU.");
5399
5400static PyObject *
5401posix_sched_yield(PyObject *self, PyObject *noargs)
5402{
5403 if (sched_yield())
5404 return posix_error();
5405 Py_RETURN_NONE;
5406}
5407
Benjamin Peterson2740af82011-08-02 17:41:34 -05005408#ifdef HAVE_SCHED_SETAFFINITY
5409
Antoine Pitrou84869872012-08-04 16:16:35 +02005410/* The minimum number of CPUs allocated in a cpu_set_t */
5411static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005412
5413PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5414"sched_setaffinity(pid, cpu_set)\n\n\
5415Set the affinity of the process with PID *pid* to *cpu_set*.");
5416
5417static PyObject *
5418posix_sched_setaffinity(PyObject *self, PyObject *args)
5419{
5420 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005421 int ncpus;
5422 size_t setsize;
5423 cpu_set_t *mask = NULL;
5424 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005425
Antoine Pitrou84869872012-08-04 16:16:35 +02005426 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5427 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005428 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005429
5430 iterator = PyObject_GetIter(iterable);
5431 if (iterator == NULL)
5432 return NULL;
5433
5434 ncpus = NCPUS_START;
5435 setsize = CPU_ALLOC_SIZE(ncpus);
5436 mask = CPU_ALLOC(ncpus);
5437 if (mask == NULL) {
5438 PyErr_NoMemory();
5439 goto error;
5440 }
5441 CPU_ZERO_S(setsize, mask);
5442
5443 while ((item = PyIter_Next(iterator))) {
5444 long cpu;
5445 if (!PyLong_Check(item)) {
5446 PyErr_Format(PyExc_TypeError,
5447 "expected an iterator of ints, "
5448 "but iterator yielded %R",
5449 Py_TYPE(item));
5450 Py_DECREF(item);
5451 goto error;
5452 }
5453 cpu = PyLong_AsLong(item);
5454 Py_DECREF(item);
5455 if (cpu < 0) {
5456 if (!PyErr_Occurred())
5457 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5458 goto error;
5459 }
5460 if (cpu > INT_MAX - 1) {
5461 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5462 goto error;
5463 }
5464 if (cpu >= ncpus) {
5465 /* Grow CPU mask to fit the CPU number */
5466 int newncpus = ncpus;
5467 cpu_set_t *newmask;
5468 size_t newsetsize;
5469 while (newncpus <= cpu) {
5470 if (newncpus > INT_MAX / 2)
5471 newncpus = cpu + 1;
5472 else
5473 newncpus = newncpus * 2;
5474 }
5475 newmask = CPU_ALLOC(newncpus);
5476 if (newmask == NULL) {
5477 PyErr_NoMemory();
5478 goto error;
5479 }
5480 newsetsize = CPU_ALLOC_SIZE(newncpus);
5481 CPU_ZERO_S(newsetsize, newmask);
5482 memcpy(newmask, mask, setsize);
5483 CPU_FREE(mask);
5484 setsize = newsetsize;
5485 mask = newmask;
5486 ncpus = newncpus;
5487 }
5488 CPU_SET_S(cpu, setsize, mask);
5489 }
5490 Py_CLEAR(iterator);
5491
5492 if (sched_setaffinity(pid, setsize, mask)) {
5493 posix_error();
5494 goto error;
5495 }
5496 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005497 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005498
5499error:
5500 if (mask)
5501 CPU_FREE(mask);
5502 Py_XDECREF(iterator);
5503 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005504}
5505
5506PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5507"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5508Return the affinity of the process with PID *pid*.\n\
5509The returned cpu_set will be of size *ncpus*.");
5510
5511static PyObject *
5512posix_sched_getaffinity(PyObject *self, PyObject *args)
5513{
5514 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005515 int cpu, ncpus, count;
5516 size_t setsize;
5517 cpu_set_t *mask = NULL;
5518 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005519
Antoine Pitrou84869872012-08-04 16:16:35 +02005520 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
5521 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005522 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005523
5524 ncpus = NCPUS_START;
5525 while (1) {
5526 setsize = CPU_ALLOC_SIZE(ncpus);
5527 mask = CPU_ALLOC(ncpus);
5528 if (mask == NULL)
5529 return PyErr_NoMemory();
5530 if (sched_getaffinity(pid, setsize, mask) == 0)
5531 break;
5532 CPU_FREE(mask);
5533 if (errno != EINVAL)
5534 return posix_error();
5535 if (ncpus > INT_MAX / 2) {
5536 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5537 "a large enough CPU set");
5538 return NULL;
5539 }
5540 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005541 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005542
5543 res = PySet_New(NULL);
5544 if (res == NULL)
5545 goto error;
5546 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5547 if (CPU_ISSET_S(cpu, setsize, mask)) {
5548 PyObject *cpu_num = PyLong_FromLong(cpu);
5549 --count;
5550 if (cpu_num == NULL)
5551 goto error;
5552 if (PySet_Add(res, cpu_num)) {
5553 Py_DECREF(cpu_num);
5554 goto error;
5555 }
5556 Py_DECREF(cpu_num);
5557 }
5558 }
5559 CPU_FREE(mask);
5560 return res;
5561
5562error:
5563 if (mask)
5564 CPU_FREE(mask);
5565 Py_XDECREF(res);
5566 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005567}
5568
Benjamin Peterson2740af82011-08-02 17:41:34 -05005569#endif /* HAVE_SCHED_SETAFFINITY */
5570
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005571#endif /* HAVE_SCHED_H */
5572
Neal Norwitzb59798b2003-03-21 01:43:31 +00005573/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005574/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5575#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005576#define DEV_PTY_FILE "/dev/ptc"
5577#define HAVE_DEV_PTMX
5578#else
5579#define DEV_PTY_FILE "/dev/ptmx"
5580#endif
5581
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005582#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005583#ifdef HAVE_PTY_H
5584#include <pty.h>
5585#else
5586#ifdef HAVE_LIBUTIL_H
5587#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005588#else
5589#ifdef HAVE_UTIL_H
5590#include <util.h>
5591#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005592#endif /* HAVE_LIBUTIL_H */
5593#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005594#ifdef HAVE_STROPTS_H
5595#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005596#endif
5597#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005598
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005599#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005600PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005601"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005602Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005603
5604static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005605posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005606{
Victor Stinner8c62be82010-05-06 00:08:46 +00005607 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005608#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005609 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005610#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005611#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005612 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005613#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005614 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005615#endif
5616#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005617
Thomas Wouters70c21a12000-07-14 14:28:33 +00005618#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005619 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
5620 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005621#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005622 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5623 if (slave_name == NULL)
5624 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00005625
Victor Stinner8c62be82010-05-06 00:08:46 +00005626 slave_fd = open(slave_name, O_RDWR);
5627 if (slave_fd < 0)
5628 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005629#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005630 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
5631 if (master_fd < 0)
5632 return posix_error();
5633 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
5634 /* change permission of slave */
5635 if (grantpt(master_fd) < 0) {
5636 PyOS_setsig(SIGCHLD, sig_saved);
5637 return posix_error();
5638 }
5639 /* unlock slave */
5640 if (unlockpt(master_fd) < 0) {
5641 PyOS_setsig(SIGCHLD, sig_saved);
5642 return posix_error();
5643 }
5644 PyOS_setsig(SIGCHLD, sig_saved);
5645 slave_name = ptsname(master_fd); /* get name of slave */
5646 if (slave_name == NULL)
5647 return posix_error();
5648 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
5649 if (slave_fd < 0)
5650 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005651#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005652 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5653 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005654#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005655 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005656#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005657#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005658#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005659
Victor Stinner8c62be82010-05-06 00:08:46 +00005660 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005661
Fred Drake8cef4cf2000-06-28 16:40:38 +00005662}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005663#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005664
5665#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005666PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005667"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00005668Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
5669Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005670To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005671
5672static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005673posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005674{
Victor Stinner8c62be82010-05-06 00:08:46 +00005675 int master_fd = -1, result = 0;
5676 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005677
Victor Stinner8c62be82010-05-06 00:08:46 +00005678 _PyImport_AcquireLock();
5679 pid = forkpty(&master_fd, NULL, NULL, NULL);
5680 if (pid == 0) {
5681 /* child: this clobbers and resets the import lock. */
5682 PyOS_AfterFork();
5683 } else {
5684 /* parent: release the import lock. */
5685 result = _PyImport_ReleaseLock();
5686 }
5687 if (pid == -1)
5688 return posix_error();
5689 if (result < 0) {
5690 /* Don't clobber the OSError if the fork failed. */
5691 PyErr_SetString(PyExc_RuntimeError,
5692 "not holding the import lock");
5693 return NULL;
5694 }
5695 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005696}
5697#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005698
Ross Lagerwall7807c352011-03-17 20:20:30 +02005699
Guido van Rossumad0ee831995-03-01 10:34:45 +00005700#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005701PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005702"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005703Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005704
Barry Warsaw53699e91996-12-10 23:23:01 +00005705static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005706posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005707{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005708 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005709}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005710#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005711
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005712
Guido van Rossumad0ee831995-03-01 10:34:45 +00005713#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005714PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005715"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005716Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005717
Barry Warsaw53699e91996-12-10 23:23:01 +00005718static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005719posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005720{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005721 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005722}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005723#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005724
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005725
Guido van Rossumad0ee831995-03-01 10:34:45 +00005726#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005727PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005728"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005729Return the current process's group 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_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005733{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005734 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005735}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005736#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005737
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005738
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005739PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005740"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005741Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005742
Barry Warsaw53699e91996-12-10 23:23:01 +00005743static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005744posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005745{
Victor Stinner8c62be82010-05-06 00:08:46 +00005746 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005747}
5748
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005749#ifdef HAVE_GETGROUPLIST
5750PyDoc_STRVAR(posix_getgrouplist__doc__,
5751"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5752Returns a list of groups to which a user belongs.\n\n\
5753 user: username to lookup\n\
5754 group: base group id of the user");
5755
5756static PyObject *
5757posix_getgrouplist(PyObject *self, PyObject *args)
5758{
5759#ifdef NGROUPS_MAX
5760#define MAX_GROUPS NGROUPS_MAX
5761#else
5762 /* defined to be 16 on Solaris7, so this should be a small number */
5763#define MAX_GROUPS 64
5764#endif
5765
5766 const char *user;
5767 int i, ngroups;
5768 PyObject *list;
5769#ifdef __APPLE__
5770 int *groups, basegid;
5771#else
5772 gid_t *groups, basegid;
5773#endif
5774 ngroups = MAX_GROUPS;
5775
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005776#ifdef __APPLE__
5777 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005778 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005779#else
5780 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
5781 _Py_Gid_Converter, &basegid))
5782 return NULL;
5783#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005784
5785#ifdef __APPLE__
5786 groups = PyMem_Malloc(ngroups * sizeof(int));
5787#else
5788 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
5789#endif
5790 if (groups == NULL)
5791 return PyErr_NoMemory();
5792
5793 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
5794 PyMem_Del(groups);
5795 return posix_error();
5796 }
5797
5798 list = PyList_New(ngroups);
5799 if (list == NULL) {
5800 PyMem_Del(groups);
5801 return NULL;
5802 }
5803
5804 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005805#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005806 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005807#else
5808 PyObject *o = _PyLong_FromGid(groups[i]);
5809#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005810 if (o == NULL) {
5811 Py_DECREF(list);
5812 PyMem_Del(groups);
5813 return NULL;
5814 }
5815 PyList_SET_ITEM(list, i, o);
5816 }
5817
5818 PyMem_Del(groups);
5819
5820 return list;
5821}
5822#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005823
Fred Drakec9680921999-12-13 16:37:25 +00005824#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005825PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005826"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005827Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00005828
5829static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005830posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00005831{
5832 PyObject *result = NULL;
5833
Fred Drakec9680921999-12-13 16:37:25 +00005834#ifdef NGROUPS_MAX
5835#define MAX_GROUPS NGROUPS_MAX
5836#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005837 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00005838#define MAX_GROUPS 64
5839#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005840 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005841
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005842 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005843 * This is a helper variable to store the intermediate result when
5844 * that happens.
5845 *
5846 * To keep the code readable the OSX behaviour is unconditional,
5847 * according to the POSIX spec this should be safe on all unix-y
5848 * systems.
5849 */
5850 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005851 int n;
Fred Drakec9680921999-12-13 16:37:25 +00005852
Victor Stinner8c62be82010-05-06 00:08:46 +00005853 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005854 if (n < 0) {
5855 if (errno == EINVAL) {
5856 n = getgroups(0, NULL);
5857 if (n == -1) {
5858 return posix_error();
5859 }
5860 if (n == 0) {
5861 /* Avoid malloc(0) */
5862 alt_grouplist = grouplist;
5863 } else {
5864 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
5865 if (alt_grouplist == NULL) {
5866 errno = EINVAL;
5867 return posix_error();
5868 }
5869 n = getgroups(n, alt_grouplist);
5870 if (n == -1) {
5871 PyMem_Free(alt_grouplist);
5872 return posix_error();
5873 }
5874 }
5875 } else {
5876 return posix_error();
5877 }
5878 }
5879 result = PyList_New(n);
5880 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005881 int i;
5882 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005883 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00005884 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00005885 Py_DECREF(result);
5886 result = NULL;
5887 break;
Fred Drakec9680921999-12-13 16:37:25 +00005888 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005889 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00005890 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005891 }
5892
5893 if (alt_grouplist != grouplist) {
5894 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005895 }
Neal Norwitze241ce82003-02-17 18:17:05 +00005896
Fred Drakec9680921999-12-13 16:37:25 +00005897 return result;
5898}
5899#endif
5900
Antoine Pitroub7572f02009-12-02 20:46:48 +00005901#ifdef HAVE_INITGROUPS
5902PyDoc_STRVAR(posix_initgroups__doc__,
5903"initgroups(username, gid) -> None\n\n\
5904Call the system initgroups() to initialize the group access list with all of\n\
5905the groups of which the specified username is a member, plus the specified\n\
5906group id.");
5907
5908static PyObject *
5909posix_initgroups(PyObject *self, PyObject *args)
5910{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005911 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00005912 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005913 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005914#ifdef __APPLE__
5915 int gid;
5916#else
5917 gid_t gid;
5918#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00005919
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005920#ifdef __APPLE__
5921 if (!PyArg_ParseTuple(args, "O&i:initgroups",
5922 PyUnicode_FSConverter, &oname,
5923 &gid))
5924#else
5925 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
5926 PyUnicode_FSConverter, &oname,
5927 _Py_Gid_Converter, &gid))
5928#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005929 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005930 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005931
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005932 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005933 Py_DECREF(oname);
5934 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00005935 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005936
Victor Stinner8c62be82010-05-06 00:08:46 +00005937 Py_INCREF(Py_None);
5938 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005939}
5940#endif
5941
Martin v. Löwis606edc12002-06-13 21:09:11 +00005942#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005943PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005944"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005945Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00005946
5947static PyObject *
5948posix_getpgid(PyObject *self, PyObject *args)
5949{
Victor Stinner8c62be82010-05-06 00:08:46 +00005950 pid_t pid, pgid;
5951 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
5952 return NULL;
5953 pgid = getpgid(pid);
5954 if (pgid < 0)
5955 return posix_error();
5956 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00005957}
5958#endif /* HAVE_GETPGID */
5959
5960
Guido van Rossumb6775db1994-08-01 11:34:53 +00005961#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005962PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005963"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005964Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005965
Barry Warsaw53699e91996-12-10 23:23:01 +00005966static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005967posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00005968{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005969#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005970 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005971#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005972 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005973#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00005974}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005975#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00005976
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005977
Guido van Rossumb6775db1994-08-01 11:34:53 +00005978#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005979PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005980"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00005981Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005982
Barry Warsaw53699e91996-12-10 23:23:01 +00005983static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005984posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005985{
Guido van Rossum64933891994-10-20 21:56:42 +00005986#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005987 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005988#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005989 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005990#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005991 return posix_error();
5992 Py_INCREF(Py_None);
5993 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005994}
5995
Guido van Rossumb6775db1994-08-01 11:34:53 +00005996#endif /* HAVE_SETPGRP */
5997
Guido van Rossumad0ee831995-03-01 10:34:45 +00005998#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005999
6000#ifdef MS_WINDOWS
6001#include <tlhelp32.h>
6002
6003static PyObject*
6004win32_getppid()
6005{
6006 HANDLE snapshot;
6007 pid_t mypid;
6008 PyObject* result = NULL;
6009 BOOL have_record;
6010 PROCESSENTRY32 pe;
6011
6012 mypid = getpid(); /* This function never fails */
6013
6014 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6015 if (snapshot == INVALID_HANDLE_VALUE)
6016 return PyErr_SetFromWindowsErr(GetLastError());
6017
6018 pe.dwSize = sizeof(pe);
6019 have_record = Process32First(snapshot, &pe);
6020 while (have_record) {
6021 if (mypid == (pid_t)pe.th32ProcessID) {
6022 /* We could cache the ulong value in a static variable. */
6023 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6024 break;
6025 }
6026
6027 have_record = Process32Next(snapshot, &pe);
6028 }
6029
6030 /* If our loop exits and our pid was not found (result will be NULL)
6031 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6032 * error anyway, so let's raise it. */
6033 if (!result)
6034 result = PyErr_SetFromWindowsErr(GetLastError());
6035
6036 CloseHandle(snapshot);
6037
6038 return result;
6039}
6040#endif /*MS_WINDOWS*/
6041
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006042PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006043"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006044Return the parent's process id. If the parent process has already exited,\n\
6045Windows machines will still return its id; others systems will return the id\n\
6046of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006047
Barry Warsaw53699e91996-12-10 23:23:01 +00006048static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006049posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006050{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006051#ifdef MS_WINDOWS
6052 return win32_getppid();
6053#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006054 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006055#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006056}
6057#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006058
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006059
Fred Drake12c6e2d1999-12-14 21:25:03 +00006060#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006061PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006062"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006063Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006064
6065static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006066posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006067{
Victor Stinner8c62be82010-05-06 00:08:46 +00006068 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006069#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006070 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006071 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006072
6073 if (GetUserNameW(user_name, &num_chars)) {
6074 /* num_chars is the number of unicode chars plus null terminator */
6075 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006076 }
6077 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006078 result = PyErr_SetFromWindowsErr(GetLastError());
6079#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006080 char *name;
6081 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006082
Victor Stinner8c62be82010-05-06 00:08:46 +00006083 errno = 0;
6084 name = getlogin();
6085 if (name == NULL) {
6086 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006087 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006088 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006089 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006090 }
6091 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006092 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006093 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006094#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006095 return result;
6096}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006097#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006098
Guido van Rossumad0ee831995-03-01 10:34:45 +00006099#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006100PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006101"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006102Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006103
Barry Warsaw53699e91996-12-10 23:23:01 +00006104static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006105posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006106{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006107 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006108}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006109#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006110
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006111
Guido van Rossumad0ee831995-03-01 10:34:45 +00006112#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006113PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006114"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006115Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006116
Barry Warsaw53699e91996-12-10 23:23:01 +00006117static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006118posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006119{
Victor Stinner8c62be82010-05-06 00:08:46 +00006120 pid_t pid;
6121 int sig;
6122 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6123 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006124 if (kill(pid, sig) == -1)
6125 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006126 Py_INCREF(Py_None);
6127 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006128}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006129#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006130
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006131#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006132PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006133"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006134Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006135
6136static PyObject *
6137posix_killpg(PyObject *self, PyObject *args)
6138{
Victor Stinner8c62be82010-05-06 00:08:46 +00006139 int sig;
6140 pid_t pgid;
6141 /* XXX some man pages make the `pgid` parameter an int, others
6142 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6143 take the same type. Moreover, pid_t is always at least as wide as
6144 int (else compilation of this module fails), which is safe. */
6145 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6146 return NULL;
6147 if (killpg(pgid, sig) == -1)
6148 return posix_error();
6149 Py_INCREF(Py_None);
6150 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006151}
6152#endif
6153
Brian Curtineb24d742010-04-12 17:16:38 +00006154#ifdef MS_WINDOWS
6155PyDoc_STRVAR(win32_kill__doc__,
6156"kill(pid, sig)\n\n\
6157Kill a process with a signal.");
6158
6159static PyObject *
6160win32_kill(PyObject *self, PyObject *args)
6161{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006162 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00006163 DWORD pid, sig, err;
6164 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006165
Victor Stinner8c62be82010-05-06 00:08:46 +00006166 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
6167 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006168
Victor Stinner8c62be82010-05-06 00:08:46 +00006169 /* Console processes which share a common console can be sent CTRL+C or
6170 CTRL+BREAK events, provided they handle said events. */
6171 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
6172 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
6173 err = GetLastError();
6174 PyErr_SetFromWindowsErr(err);
6175 }
6176 else
6177 Py_RETURN_NONE;
6178 }
Brian Curtineb24d742010-04-12 17:16:38 +00006179
Victor Stinner8c62be82010-05-06 00:08:46 +00006180 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6181 attempt to open and terminate the process. */
6182 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
6183 if (handle == NULL) {
6184 err = GetLastError();
6185 return PyErr_SetFromWindowsErr(err);
6186 }
Brian Curtineb24d742010-04-12 17:16:38 +00006187
Victor Stinner8c62be82010-05-06 00:08:46 +00006188 if (TerminateProcess(handle, sig) == 0) {
6189 err = GetLastError();
6190 result = PyErr_SetFromWindowsErr(err);
6191 } else {
6192 Py_INCREF(Py_None);
6193 result = Py_None;
6194 }
Brian Curtineb24d742010-04-12 17:16:38 +00006195
Victor Stinner8c62be82010-05-06 00:08:46 +00006196 CloseHandle(handle);
6197 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006198}
6199#endif /* MS_WINDOWS */
6200
Guido van Rossumc0125471996-06-28 18:55:32 +00006201#ifdef HAVE_PLOCK
6202
6203#ifdef HAVE_SYS_LOCK_H
6204#include <sys/lock.h>
6205#endif
6206
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006207PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006208"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006209Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006210
Barry Warsaw53699e91996-12-10 23:23:01 +00006211static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006212posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006213{
Victor Stinner8c62be82010-05-06 00:08:46 +00006214 int op;
6215 if (!PyArg_ParseTuple(args, "i:plock", &op))
6216 return NULL;
6217 if (plock(op) == -1)
6218 return posix_error();
6219 Py_INCREF(Py_None);
6220 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006221}
6222#endif
6223
Guido van Rossumb6775db1994-08-01 11:34:53 +00006224#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006225PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006226"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006227Set the current process's user id.");
6228
Barry Warsaw53699e91996-12-10 23:23:01 +00006229static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006230posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006231{
Victor Stinner8c62be82010-05-06 00:08:46 +00006232 uid_t uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006233 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006234 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006235 if (setuid(uid) < 0)
6236 return posix_error();
6237 Py_INCREF(Py_None);
6238 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006239}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006240#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006241
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006242
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006243#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006244PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006245"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006246Set the current process's effective user id.");
6247
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006248static PyObject *
6249posix_seteuid (PyObject *self, PyObject *args)
6250{
Victor Stinner8c62be82010-05-06 00:08:46 +00006251 uid_t euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006252 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006253 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006254 if (seteuid(euid) < 0) {
6255 return posix_error();
6256 } else {
6257 Py_INCREF(Py_None);
6258 return Py_None;
6259 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006260}
6261#endif /* HAVE_SETEUID */
6262
6263#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006264PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006265"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006266Set the current process's effective group id.");
6267
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006268static PyObject *
6269posix_setegid (PyObject *self, PyObject *args)
6270{
Victor Stinner8c62be82010-05-06 00:08:46 +00006271 gid_t egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006272 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006273 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006274 if (setegid(egid) < 0) {
6275 return posix_error();
6276 } else {
6277 Py_INCREF(Py_None);
6278 return Py_None;
6279 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006280}
6281#endif /* HAVE_SETEGID */
6282
6283#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006284PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006285"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006286Set the current process's real and effective user ids.");
6287
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006288static PyObject *
6289posix_setreuid (PyObject *self, PyObject *args)
6290{
Victor Stinner8c62be82010-05-06 00:08:46 +00006291 uid_t ruid, euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006292 if (!PyArg_ParseTuple(args, "O&O&:setreuid",
6293 _Py_Uid_Converter, &ruid,
6294 _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006295 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006296 if (setreuid(ruid, euid) < 0) {
6297 return posix_error();
6298 } else {
6299 Py_INCREF(Py_None);
6300 return Py_None;
6301 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006302}
6303#endif /* HAVE_SETREUID */
6304
6305#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006306PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006307"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006308Set the current process's real and effective group ids.");
6309
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006310static PyObject *
6311posix_setregid (PyObject *self, PyObject *args)
6312{
Victor Stinner8c62be82010-05-06 00:08:46 +00006313 gid_t rgid, egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006314 if (!PyArg_ParseTuple(args, "O&O&:setregid",
6315 _Py_Gid_Converter, &rgid,
6316 _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006317 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006318 if (setregid(rgid, egid) < 0) {
6319 return posix_error();
6320 } else {
6321 Py_INCREF(Py_None);
6322 return Py_None;
6323 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006324}
6325#endif /* HAVE_SETREGID */
6326
Guido van Rossumb6775db1994-08-01 11:34:53 +00006327#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006328PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006329"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006330Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006331
Barry Warsaw53699e91996-12-10 23:23:01 +00006332static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006333posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006334{
Victor Stinner8c62be82010-05-06 00:08:46 +00006335 gid_t gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006336 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006337 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006338 if (setgid(gid) < 0)
6339 return posix_error();
6340 Py_INCREF(Py_None);
6341 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006342}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006343#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006344
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006345#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006346PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006347"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006348Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006349
6350static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006351posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006352{
Victor Stinner8c62be82010-05-06 00:08:46 +00006353 int i, len;
6354 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006355
Victor Stinner8c62be82010-05-06 00:08:46 +00006356 if (!PySequence_Check(groups)) {
6357 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6358 return NULL;
6359 }
6360 len = PySequence_Size(groups);
6361 if (len > MAX_GROUPS) {
6362 PyErr_SetString(PyExc_ValueError, "too many groups");
6363 return NULL;
6364 }
6365 for(i = 0; i < len; i++) {
6366 PyObject *elem;
6367 elem = PySequence_GetItem(groups, i);
6368 if (!elem)
6369 return NULL;
6370 if (!PyLong_Check(elem)) {
6371 PyErr_SetString(PyExc_TypeError,
6372 "groups must be integers");
6373 Py_DECREF(elem);
6374 return NULL;
6375 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006376 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006377 Py_DECREF(elem);
6378 return NULL;
6379 }
6380 }
6381 Py_DECREF(elem);
6382 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006383
Victor Stinner8c62be82010-05-06 00:08:46 +00006384 if (setgroups(len, grouplist) < 0)
6385 return posix_error();
6386 Py_INCREF(Py_None);
6387 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006388}
6389#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006390
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006391#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6392static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006393wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006394{
Victor Stinner8c62be82010-05-06 00:08:46 +00006395 PyObject *result;
6396 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006397 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006398
Victor Stinner8c62be82010-05-06 00:08:46 +00006399 if (pid == -1)
6400 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006401
Victor Stinner8c62be82010-05-06 00:08:46 +00006402 if (struct_rusage == NULL) {
6403 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6404 if (m == NULL)
6405 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006406 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006407 Py_DECREF(m);
6408 if (struct_rusage == NULL)
6409 return NULL;
6410 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006411
Victor Stinner8c62be82010-05-06 00:08:46 +00006412 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6413 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6414 if (!result)
6415 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006416
6417#ifndef doubletime
6418#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6419#endif
6420
Victor Stinner8c62be82010-05-06 00:08:46 +00006421 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006422 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006423 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006424 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006425#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006426 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6427 SET_INT(result, 2, ru->ru_maxrss);
6428 SET_INT(result, 3, ru->ru_ixrss);
6429 SET_INT(result, 4, ru->ru_idrss);
6430 SET_INT(result, 5, ru->ru_isrss);
6431 SET_INT(result, 6, ru->ru_minflt);
6432 SET_INT(result, 7, ru->ru_majflt);
6433 SET_INT(result, 8, ru->ru_nswap);
6434 SET_INT(result, 9, ru->ru_inblock);
6435 SET_INT(result, 10, ru->ru_oublock);
6436 SET_INT(result, 11, ru->ru_msgsnd);
6437 SET_INT(result, 12, ru->ru_msgrcv);
6438 SET_INT(result, 13, ru->ru_nsignals);
6439 SET_INT(result, 14, ru->ru_nvcsw);
6440 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006441#undef SET_INT
6442
Victor Stinner8c62be82010-05-06 00:08:46 +00006443 if (PyErr_Occurred()) {
6444 Py_DECREF(result);
6445 return NULL;
6446 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006447
Victor Stinner8c62be82010-05-06 00:08:46 +00006448 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006449}
6450#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6451
6452#ifdef HAVE_WAIT3
6453PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006454"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006455Wait for completion of a child process.");
6456
6457static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006458posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006459{
Victor Stinner8c62be82010-05-06 00:08:46 +00006460 pid_t pid;
6461 int options;
6462 struct rusage ru;
6463 WAIT_TYPE status;
6464 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006465
Victor Stinner4195b5c2012-02-08 23:03:19 +01006466 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006467 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006468
Victor Stinner8c62be82010-05-06 00:08:46 +00006469 Py_BEGIN_ALLOW_THREADS
6470 pid = wait3(&status, options, &ru);
6471 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006472
Victor Stinner4195b5c2012-02-08 23:03:19 +01006473 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006474}
6475#endif /* HAVE_WAIT3 */
6476
6477#ifdef HAVE_WAIT4
6478PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006479"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006480Wait for completion of a given child process.");
6481
6482static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006483posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006484{
Victor Stinner8c62be82010-05-06 00:08:46 +00006485 pid_t pid;
6486 int options;
6487 struct rusage ru;
6488 WAIT_TYPE status;
6489 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006490
Victor Stinner4195b5c2012-02-08 23:03:19 +01006491 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006492 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006493
Victor Stinner8c62be82010-05-06 00:08:46 +00006494 Py_BEGIN_ALLOW_THREADS
6495 pid = wait4(pid, &status, options, &ru);
6496 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006497
Victor Stinner4195b5c2012-02-08 23:03:19 +01006498 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006499}
6500#endif /* HAVE_WAIT4 */
6501
Ross Lagerwall7807c352011-03-17 20:20:30 +02006502#if defined(HAVE_WAITID) && !defined(__APPLE__)
6503PyDoc_STRVAR(posix_waitid__doc__,
6504"waitid(idtype, id, options) -> waitid_result\n\n\
6505Wait for the completion of one or more child processes.\n\n\
6506idtype can be P_PID, P_PGID or P_ALL.\n\
6507id specifies the pid to wait on.\n\
6508options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6509or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6510Returns either waitid_result or None if WNOHANG is specified and there are\n\
6511no children in a waitable state.");
6512
6513static PyObject *
6514posix_waitid(PyObject *self, PyObject *args)
6515{
6516 PyObject *result;
6517 idtype_t idtype;
6518 id_t id;
6519 int options, res;
6520 siginfo_t si;
6521 si.si_pid = 0;
6522 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6523 return NULL;
6524 Py_BEGIN_ALLOW_THREADS
6525 res = waitid(idtype, id, &si, options);
6526 Py_END_ALLOW_THREADS
6527 if (res == -1)
6528 return posix_error();
6529
6530 if (si.si_pid == 0)
6531 Py_RETURN_NONE;
6532
6533 result = PyStructSequence_New(&WaitidResultType);
6534 if (!result)
6535 return NULL;
6536
6537 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006538 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006539 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6540 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6541 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6542 if (PyErr_Occurred()) {
6543 Py_DECREF(result);
6544 return NULL;
6545 }
6546
6547 return result;
6548}
6549#endif
6550
Guido van Rossumb6775db1994-08-01 11:34:53 +00006551#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006552PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006553"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006554Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006555
Barry Warsaw53699e91996-12-10 23:23:01 +00006556static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006557posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006558{
Victor Stinner8c62be82010-05-06 00:08:46 +00006559 pid_t pid;
6560 int options;
6561 WAIT_TYPE status;
6562 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006563
Victor Stinner8c62be82010-05-06 00:08:46 +00006564 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6565 return NULL;
6566 Py_BEGIN_ALLOW_THREADS
6567 pid = waitpid(pid, &status, options);
6568 Py_END_ALLOW_THREADS
6569 if (pid == -1)
6570 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006571
Victor Stinner8c62be82010-05-06 00:08:46 +00006572 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006573}
6574
Tim Petersab034fa2002-02-01 11:27:43 +00006575#elif defined(HAVE_CWAIT)
6576
6577/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006578PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006579"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006580"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006581
6582static PyObject *
6583posix_waitpid(PyObject *self, PyObject *args)
6584{
Victor Stinner8c62be82010-05-06 00:08:46 +00006585 Py_intptr_t pid;
6586 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006587
Victor Stinner8c62be82010-05-06 00:08:46 +00006588 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6589 return NULL;
6590 Py_BEGIN_ALLOW_THREADS
6591 pid = _cwait(&status, pid, options);
6592 Py_END_ALLOW_THREADS
6593 if (pid == -1)
6594 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006595
Victor Stinner8c62be82010-05-06 00:08:46 +00006596 /* shift the status left a byte so this is more like the POSIX waitpid */
6597 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006598}
6599#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006600
Guido van Rossumad0ee831995-03-01 10:34:45 +00006601#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006602PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006603"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006604Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006605
Barry Warsaw53699e91996-12-10 23:23:01 +00006606static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006607posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006608{
Victor Stinner8c62be82010-05-06 00:08:46 +00006609 pid_t pid;
6610 WAIT_TYPE status;
6611 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006612
Victor Stinner8c62be82010-05-06 00:08:46 +00006613 Py_BEGIN_ALLOW_THREADS
6614 pid = wait(&status);
6615 Py_END_ALLOW_THREADS
6616 if (pid == -1)
6617 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006618
Victor Stinner8c62be82010-05-06 00:08:46 +00006619 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006620}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006621#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006622
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006623
Larry Hastings9cf065c2012-06-22 16:30:09 -07006624#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
6625PyDoc_STRVAR(readlink__doc__,
6626"readlink(path, *, dir_fd=None) -> path\n\n\
6627Return a string representing the path to which the symbolic link points.\n\
6628\n\
6629If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6630 and path should be relative; path will then be relative to that directory.\n\
6631dir_fd may not be implemented on your platform.\n\
6632 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006633#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006634
Guido van Rossumb6775db1994-08-01 11:34:53 +00006635#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006636
Barry Warsaw53699e91996-12-10 23:23:01 +00006637static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006638posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006639{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006640 path_t path;
6641 int dir_fd = DEFAULT_DIR_FD;
6642 char buffer[MAXPATHLEN];
6643 ssize_t length;
6644 PyObject *return_value = NULL;
6645 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00006646
Larry Hastings9cf065c2012-06-22 16:30:09 -07006647 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01006648 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07006649 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
6650 path_converter, &path,
6651#ifdef HAVE_READLINKAT
6652 dir_fd_converter, &dir_fd
6653#else
6654 dir_fd_unavailable, &dir_fd
6655#endif
6656 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00006657 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00006658
Victor Stinner8c62be82010-05-06 00:08:46 +00006659 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07006660#ifdef HAVE_READLINKAT
6661 if (dir_fd != DEFAULT_DIR_FD)
6662 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00006663 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07006664#endif
6665 length = readlink(path.narrow, buffer, sizeof(buffer));
6666 Py_END_ALLOW_THREADS
6667
6668 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01006669 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006670 goto exit;
6671 }
6672
6673 if (PyUnicode_Check(path.object))
6674 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
6675 else
6676 return_value = PyBytes_FromStringAndSize(buffer, length);
6677exit:
6678 path_cleanup(&path);
6679 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006680}
Larry Hastings9cf065c2012-06-22 16:30:09 -07006681
6682
Guido van Rossumb6775db1994-08-01 11:34:53 +00006683#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006684
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006685
Larry Hastings9cf065c2012-06-22 16:30:09 -07006686#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006687PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07006688"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
6689Create a symbolic link pointing to src named dst.\n\n\
6690target_is_directory is required on Windows if the target is to be\n\
6691 interpreted as a directory. (On Windows, symlink requires\n\
6692 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
6693 target_is_directory is ignored on non-Windows platforms.\n\
6694\n\
6695If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6696 and path should be relative; path will then be relative to that directory.\n\
6697dir_fd may not be implemented on your platform.\n\
6698 If it is unavailable, using it will raise a NotImplementedError.");
6699
6700#if defined(MS_WINDOWS)
6701
6702/* Grab CreateSymbolicLinkW dynamically from kernel32 */
6703static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
6704static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
6705static int
6706check_CreateSymbolicLink()
6707{
6708 HINSTANCE hKernel32;
6709 /* only recheck */
6710 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
6711 return 1;
6712 hKernel32 = GetModuleHandleW(L"KERNEL32");
6713 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
6714 "CreateSymbolicLinkW");
6715 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
6716 "CreateSymbolicLinkA");
6717 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
6718}
6719
6720#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006721
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006722static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006723posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006724{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006725 path_t src;
6726 path_t dst;
6727 int dir_fd = DEFAULT_DIR_FD;
6728 int target_is_directory = 0;
6729 static char *keywords[] = {"src", "dst", "target_is_directory",
6730 "dir_fd", NULL};
6731 PyObject *return_value;
6732#ifdef MS_WINDOWS
6733 DWORD result;
6734#else
6735 int result;
6736#endif
6737
6738 memset(&src, 0, sizeof(src));
Victor Stinner292c8352012-10-30 02:17:38 +01006739 src.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07006740 src.argument_name = "src";
6741 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01006742 dst.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07006743 dst.argument_name = "dst";
6744
6745#ifdef MS_WINDOWS
6746 if (!check_CreateSymbolicLink()) {
6747 PyErr_SetString(PyExc_NotImplementedError,
6748 "CreateSymbolicLink functions not found");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03006749 return NULL;
6750 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07006751 if (!win32_can_symlink) {
6752 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03006753 return NULL;
6754 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07006755#endif
6756
6757 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
6758 keywords,
6759 path_converter, &src,
6760 path_converter, &dst,
6761 &target_is_directory,
6762#ifdef HAVE_SYMLINKAT
6763 dir_fd_converter, &dir_fd
6764#else
6765 dir_fd_unavailable, &dir_fd
6766#endif
6767 ))
6768 return NULL;
6769
6770 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
6771 PyErr_SetString(PyExc_ValueError,
6772 "symlink: src and dst must be the same type");
6773 return_value = NULL;
6774 goto exit;
6775 }
6776
6777#ifdef MS_WINDOWS
6778 Py_BEGIN_ALLOW_THREADS
6779 if (dst.wide)
6780 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
6781 target_is_directory);
6782 else
6783 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
6784 target_is_directory);
6785 Py_END_ALLOW_THREADS
6786
6787 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01006788 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006789 goto exit;
6790 }
6791
6792#else
6793
6794 Py_BEGIN_ALLOW_THREADS
6795#if HAVE_SYMLINKAT
6796 if (dir_fd != DEFAULT_DIR_FD)
6797 result = symlinkat(src.narrow, dir_fd, dst.narrow);
6798 else
6799#endif
6800 result = symlink(src.narrow, dst.narrow);
6801 Py_END_ALLOW_THREADS
6802
6803 if (result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01006804 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006805 goto exit;
6806 }
6807#endif
6808
6809 return_value = Py_None;
6810 Py_INCREF(Py_None);
6811 goto exit; /* silence "unused label" warning */
6812exit:
6813 path_cleanup(&src);
6814 path_cleanup(&dst);
6815 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006816}
Larry Hastings9cf065c2012-06-22 16:30:09 -07006817
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006818#endif /* HAVE_SYMLINK */
6819
Larry Hastings9cf065c2012-06-22 16:30:09 -07006820
Brian Curtind40e6f72010-07-08 21:39:08 +00006821#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
6822
Brian Curtind40e6f72010-07-08 21:39:08 +00006823static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006824win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00006825{
6826 wchar_t *path;
6827 DWORD n_bytes_returned;
6828 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006829 PyObject *po, *result;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03006830 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00006831 HANDLE reparse_point_handle;
6832
6833 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
6834 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
6835 wchar_t *print_name;
6836
Larry Hastings9cf065c2012-06-22 16:30:09 -07006837 static char *keywords[] = {"path", "dir_fd", NULL};
6838
6839 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
6840 &po,
6841 dir_fd_unavailable, &dir_fd
6842 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02006843 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07006844
Victor Stinnereb5657a2011-09-30 01:44:27 +02006845 path = PyUnicode_AsUnicode(po);
6846 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00006847 return NULL;
6848
6849 /* First get a handle to the reparse point */
6850 Py_BEGIN_ALLOW_THREADS
6851 reparse_point_handle = CreateFileW(
6852 path,
6853 0,
6854 0,
6855 0,
6856 OPEN_EXISTING,
6857 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
6858 0);
6859 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006860
Brian Curtind40e6f72010-07-08 21:39:08 +00006861 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006862 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006863
Brian Curtind40e6f72010-07-08 21:39:08 +00006864 Py_BEGIN_ALLOW_THREADS
6865 /* New call DeviceIoControl to read the reparse point */
6866 io_result = DeviceIoControl(
6867 reparse_point_handle,
6868 FSCTL_GET_REPARSE_POINT,
6869 0, 0, /* in buffer */
6870 target_buffer, sizeof(target_buffer),
6871 &n_bytes_returned,
6872 0 /* we're not using OVERLAPPED_IO */
6873 );
6874 CloseHandle(reparse_point_handle);
6875 Py_END_ALLOW_THREADS
6876
6877 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006878 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00006879
6880 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
6881 {
6882 PyErr_SetString(PyExc_ValueError,
6883 "not a symbolic link");
6884 return NULL;
6885 }
Brian Curtin74e45612010-07-09 15:58:59 +00006886 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
6887 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
6888
6889 result = PyUnicode_FromWideChar(print_name,
6890 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00006891 return result;
6892}
6893
6894#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
6895
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006896
Larry Hastings605a62d2012-06-24 04:33:36 -07006897static PyStructSequence_Field times_result_fields[] = {
6898 {"user", "user time"},
6899 {"system", "system time"},
6900 {"children_user", "user time of children"},
6901 {"children_system", "system time of children"},
6902 {"elapsed", "elapsed time since an arbitrary point in the past"},
6903 {NULL}
6904};
6905
6906PyDoc_STRVAR(times_result__doc__,
6907"times_result: Result from os.times().\n\n\
6908This object may be accessed either as a tuple of\n\
6909 (user, system, children_user, children_system, elapsed),\n\
6910or via the attributes user, system, children_user, children_system,\n\
6911and elapsed.\n\
6912\n\
6913See os.times for more information.");
6914
6915static PyStructSequence_Desc times_result_desc = {
6916 "times_result", /* name */
6917 times_result__doc__, /* doc */
6918 times_result_fields,
6919 5
6920};
6921
6922static PyTypeObject TimesResultType;
6923
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006924#ifdef MS_WINDOWS
6925#define HAVE_TIMES /* mandatory, for the method table */
6926#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07006927
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006928#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07006929
6930static PyObject *
6931build_times_result(double user, double system,
6932 double children_user, double children_system,
6933 double elapsed)
6934{
6935 PyObject *value = PyStructSequence_New(&TimesResultType);
6936 if (value == NULL)
6937 return NULL;
6938
6939#define SET(i, field) \
6940 { \
6941 PyObject *o = PyFloat_FromDouble(field); \
6942 if (!o) { \
6943 Py_DECREF(value); \
6944 return NULL; \
6945 } \
6946 PyStructSequence_SET_ITEM(value, i, o); \
6947 } \
6948
6949 SET(0, user);
6950 SET(1, system);
6951 SET(2, children_user);
6952 SET(3, children_system);
6953 SET(4, elapsed);
6954
6955#undef SET
6956
6957 return value;
6958}
6959
6960PyDoc_STRVAR(posix_times__doc__,
6961"times() -> times_result\n\n\
6962Return an object containing floating point numbers indicating process\n\
6963times. The object behaves like a named tuple with these fields:\n\
6964 (utime, stime, cutime, cstime, elapsed_time)");
6965
Jesus Ceaab70e2a2012-10-05 01:48:08 +02006966#if defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00006967static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006968posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006969{
Victor Stinner8c62be82010-05-06 00:08:46 +00006970 FILETIME create, exit, kernel, user;
6971 HANDLE hProc;
6972 hProc = GetCurrentProcess();
6973 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6974 /* The fields of a FILETIME structure are the hi and lo part
6975 of a 64-bit value expressed in 100 nanosecond units.
6976 1e7 is one second in such units; 1e-7 the inverse.
6977 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6978 */
Larry Hastings605a62d2012-06-24 04:33:36 -07006979 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00006980 (double)(user.dwHighDateTime*429.4967296 +
6981 user.dwLowDateTime*1e-7),
6982 (double)(kernel.dwHighDateTime*429.4967296 +
6983 kernel.dwLowDateTime*1e-7),
6984 (double)0,
6985 (double)0,
6986 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006987}
Jesus Ceaab70e2a2012-10-05 01:48:08 +02006988#else /* Not Windows */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006989#define NEED_TICKS_PER_SECOND
6990static long ticks_per_second = -1;
6991static PyObject *
6992posix_times(PyObject *self, PyObject *noargs)
6993{
6994 struct tms t;
6995 clock_t c;
6996 errno = 0;
6997 c = times(&t);
6998 if (c == (clock_t) -1)
6999 return posix_error();
7000 return build_times_result(
7001 (double)t.tms_utime / ticks_per_second,
7002 (double)t.tms_stime / ticks_per_second,
7003 (double)t.tms_cutime / ticks_per_second,
7004 (double)t.tms_cstime / ticks_per_second,
7005 (double)c / ticks_per_second);
7006}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007007#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007008
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007009#endif /* HAVE_TIMES */
7010
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007011
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007012#ifdef HAVE_GETSID
7013PyDoc_STRVAR(posix_getsid__doc__,
7014"getsid(pid) -> sid\n\n\
7015Call the system call getsid().");
7016
7017static PyObject *
7018posix_getsid(PyObject *self, PyObject *args)
7019{
Victor Stinner8c62be82010-05-06 00:08:46 +00007020 pid_t pid;
7021 int sid;
7022 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7023 return NULL;
7024 sid = getsid(pid);
7025 if (sid < 0)
7026 return posix_error();
7027 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007028}
7029#endif /* HAVE_GETSID */
7030
7031
Guido van Rossumb6775db1994-08-01 11:34:53 +00007032#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007033PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007034"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007035Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007036
Barry Warsaw53699e91996-12-10 23:23:01 +00007037static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007038posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007039{
Victor Stinner8c62be82010-05-06 00:08:46 +00007040 if (setsid() < 0)
7041 return posix_error();
7042 Py_INCREF(Py_None);
7043 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007044}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007045#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007046
Guido van Rossumb6775db1994-08-01 11:34:53 +00007047#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007048PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007049"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007050Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007051
Barry Warsaw53699e91996-12-10 23:23:01 +00007052static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007053posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007054{
Victor Stinner8c62be82010-05-06 00:08:46 +00007055 pid_t pid;
7056 int pgrp;
7057 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7058 return NULL;
7059 if (setpgid(pid, pgrp) < 0)
7060 return posix_error();
7061 Py_INCREF(Py_None);
7062 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007063}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007064#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007065
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007066
Guido van Rossumb6775db1994-08-01 11:34:53 +00007067#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007068PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007069"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007070Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007071
Barry Warsaw53699e91996-12-10 23:23:01 +00007072static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007073posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007074{
Victor Stinner8c62be82010-05-06 00:08:46 +00007075 int fd;
7076 pid_t pgid;
7077 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7078 return NULL;
7079 pgid = tcgetpgrp(fd);
7080 if (pgid < 0)
7081 return posix_error();
7082 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007083}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007084#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007085
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007086
Guido van Rossumb6775db1994-08-01 11:34:53 +00007087#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007088PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007089"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007090Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007091
Barry Warsaw53699e91996-12-10 23:23:01 +00007092static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007093posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007094{
Victor Stinner8c62be82010-05-06 00:08:46 +00007095 int fd;
7096 pid_t pgid;
7097 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7098 return NULL;
7099 if (tcsetpgrp(fd, pgid) < 0)
7100 return posix_error();
7101 Py_INCREF(Py_None);
7102 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007103}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007104#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007105
Guido van Rossum687dd131993-05-17 08:34:16 +00007106/* Functions acting on file descriptors */
7107
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007108PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007109"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7110Open a file for low level IO. Returns a file handle (integer).\n\
7111\n\
7112If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7113 and path should be relative; path will then be relative to that directory.\n\
7114dir_fd may not be implemented on your platform.\n\
7115 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007116
Barry Warsaw53699e91996-12-10 23:23:01 +00007117static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007118posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007119{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007120 path_t path;
7121 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007122 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007123 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007124 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007125 PyObject *return_value = NULL;
7126 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007127
Larry Hastings9cf065c2012-06-22 16:30:09 -07007128 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007129 path.function_name = "open";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007130 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7131 path_converter, &path,
7132 &flags, &mode,
7133#ifdef HAVE_OPENAT
7134 dir_fd_converter, &dir_fd
7135#else
7136 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007137#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007138 ))
7139 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007140
Victor Stinner8c62be82010-05-06 00:08:46 +00007141 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007142#ifdef MS_WINDOWS
7143 if (path.wide)
7144 fd = _wopen(path.wide, flags, mode);
7145 else
7146#endif
7147#ifdef HAVE_OPENAT
7148 if (dir_fd != DEFAULT_DIR_FD)
7149 fd = openat(dir_fd, path.narrow, flags, mode);
7150 else
7151#endif
7152 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007153 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007154
Larry Hastings9cf065c2012-06-22 16:30:09 -07007155 if (fd == -1) {
Victor Stinner4e7d2d42012-11-05 01:20:58 +01007156 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path.object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007157 goto exit;
7158 }
7159
7160 return_value = PyLong_FromLong((long)fd);
7161
7162exit:
7163 path_cleanup(&path);
7164 return return_value;
7165}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007166
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007167PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007168"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007169Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007170
Barry Warsaw53699e91996-12-10 23:23:01 +00007171static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007172posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007173{
Victor Stinner8c62be82010-05-06 00:08:46 +00007174 int fd, res;
7175 if (!PyArg_ParseTuple(args, "i:close", &fd))
7176 return NULL;
7177 if (!_PyVerify_fd(fd))
7178 return posix_error();
7179 Py_BEGIN_ALLOW_THREADS
7180 res = close(fd);
7181 Py_END_ALLOW_THREADS
7182 if (res < 0)
7183 return posix_error();
7184 Py_INCREF(Py_None);
7185 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007186}
7187
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007188
Victor Stinner8c62be82010-05-06 00:08:46 +00007189PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007190"closerange(fd_low, fd_high)\n\n\
7191Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7192
7193static PyObject *
7194posix_closerange(PyObject *self, PyObject *args)
7195{
Victor Stinner8c62be82010-05-06 00:08:46 +00007196 int fd_from, fd_to, i;
7197 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7198 return NULL;
7199 Py_BEGIN_ALLOW_THREADS
7200 for (i = fd_from; i < fd_to; i++)
7201 if (_PyVerify_fd(i))
7202 close(i);
7203 Py_END_ALLOW_THREADS
7204 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007205}
7206
7207
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007208PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007209"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007210Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007211
Barry Warsaw53699e91996-12-10 23:23:01 +00007212static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007213posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007214{
Victor Stinner8c62be82010-05-06 00:08:46 +00007215 int fd;
7216 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7217 return NULL;
7218 if (!_PyVerify_fd(fd))
7219 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007220 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007221 if (fd < 0)
7222 return posix_error();
7223 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007224}
7225
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007226
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007227PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007228"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007229Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007230
Barry Warsaw53699e91996-12-10 23:23:01 +00007231static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007232posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007233{
Victor Stinner8c62be82010-05-06 00:08:46 +00007234 int fd, fd2, res;
7235 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
7236 return NULL;
7237 if (!_PyVerify_fd_dup2(fd, fd2))
7238 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007239 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00007240 if (res < 0)
7241 return posix_error();
7242 Py_INCREF(Py_None);
7243 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007244}
7245
Ross Lagerwall7807c352011-03-17 20:20:30 +02007246#ifdef HAVE_LOCKF
7247PyDoc_STRVAR(posix_lockf__doc__,
7248"lockf(fd, cmd, len)\n\n\
7249Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7250fd is an open file descriptor.\n\
7251cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7252F_TEST.\n\
7253len specifies the section of the file to lock.");
7254
7255static PyObject *
7256posix_lockf(PyObject *self, PyObject *args)
7257{
7258 int fd, cmd, res;
7259 off_t len;
7260 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7261 &fd, &cmd, _parse_off_t, &len))
7262 return NULL;
7263
7264 Py_BEGIN_ALLOW_THREADS
7265 res = lockf(fd, cmd, len);
7266 Py_END_ALLOW_THREADS
7267
7268 if (res < 0)
7269 return posix_error();
7270
7271 Py_RETURN_NONE;
7272}
7273#endif
7274
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007275
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007276PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007277"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007278Set the current position of a file descriptor.\n\
7279Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007280
Barry Warsaw53699e91996-12-10 23:23:01 +00007281static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007282posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007283{
Victor Stinner8c62be82010-05-06 00:08:46 +00007284 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007285#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007286 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007287#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007288 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007289#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007290 PyObject *posobj;
7291 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007292 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007293#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007294 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7295 switch (how) {
7296 case 0: how = SEEK_SET; break;
7297 case 1: how = SEEK_CUR; break;
7298 case 2: how = SEEK_END; break;
7299 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007300#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007301
Ross Lagerwall8e749672011-03-17 21:54:07 +02007302#if !defined(HAVE_LARGEFILE_SUPPORT)
7303 pos = PyLong_AsLong(posobj);
7304#else
7305 pos = PyLong_AsLongLong(posobj);
7306#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007307 if (PyErr_Occurred())
7308 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007309
Victor Stinner8c62be82010-05-06 00:08:46 +00007310 if (!_PyVerify_fd(fd))
7311 return posix_error();
7312 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007313#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007314 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007315#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007316 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007317#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007318 Py_END_ALLOW_THREADS
7319 if (res < 0)
7320 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007321
7322#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007323 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007324#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007325 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007326#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007327}
7328
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007329
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007330PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007331"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007332Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007333
Barry Warsaw53699e91996-12-10 23:23:01 +00007334static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007335posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007336{
Victor Stinner8c62be82010-05-06 00:08:46 +00007337 int fd, size;
7338 Py_ssize_t n;
7339 PyObject *buffer;
7340 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7341 return NULL;
7342 if (size < 0) {
7343 errno = EINVAL;
7344 return posix_error();
7345 }
7346 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7347 if (buffer == NULL)
7348 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007349 if (!_PyVerify_fd(fd)) {
7350 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007351 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007352 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007353 Py_BEGIN_ALLOW_THREADS
7354 n = read(fd, PyBytes_AS_STRING(buffer), size);
7355 Py_END_ALLOW_THREADS
7356 if (n < 0) {
7357 Py_DECREF(buffer);
7358 return posix_error();
7359 }
7360 if (n != size)
7361 _PyBytes_Resize(&buffer, n);
7362 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007363}
7364
Ross Lagerwall7807c352011-03-17 20:20:30 +02007365#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7366 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007367static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007368iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7369{
7370 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007371 Py_ssize_t blen, total = 0;
7372
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007373 *iov = PyMem_New(struct iovec, cnt);
7374 if (*iov == NULL) {
7375 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007376 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007377 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007378
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007379 *buf = PyMem_New(Py_buffer, cnt);
7380 if (*buf == NULL) {
7381 PyMem_Del(*iov);
7382 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007383 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007384 }
7385
7386 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007387 PyObject *item = PySequence_GetItem(seq, i);
7388 if (item == NULL)
7389 goto fail;
7390 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7391 Py_DECREF(item);
7392 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007393 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007394 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007395 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007396 blen = (*buf)[i].len;
7397 (*iov)[i].iov_len = blen;
7398 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007399 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007400 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007401
7402fail:
7403 PyMem_Del(*iov);
7404 for (j = 0; j < i; j++) {
7405 PyBuffer_Release(&(*buf)[j]);
7406 }
7407 PyMem_Del(*buf);
7408 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007409}
7410
7411static void
7412iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7413{
7414 int i;
7415 PyMem_Del(iov);
7416 for (i = 0; i < cnt; i++) {
7417 PyBuffer_Release(&buf[i]);
7418 }
7419 PyMem_Del(buf);
7420}
7421#endif
7422
Ross Lagerwall7807c352011-03-17 20:20:30 +02007423#ifdef HAVE_READV
7424PyDoc_STRVAR(posix_readv__doc__,
7425"readv(fd, buffers) -> bytesread\n\n\
7426Read from a file descriptor into a number of writable buffers. buffers\n\
7427is an arbitrary sequence of writable buffers.\n\
7428Returns the total number of bytes read.");
7429
7430static PyObject *
7431posix_readv(PyObject *self, PyObject *args)
7432{
7433 int fd, cnt;
7434 Py_ssize_t n;
7435 PyObject *seq;
7436 struct iovec *iov;
7437 Py_buffer *buf;
7438
7439 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7440 return NULL;
7441 if (!PySequence_Check(seq)) {
7442 PyErr_SetString(PyExc_TypeError,
7443 "readv() arg 2 must be a sequence");
7444 return NULL;
7445 }
7446 cnt = PySequence_Size(seq);
7447
7448 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7449 return NULL;
7450
7451 Py_BEGIN_ALLOW_THREADS
7452 n = readv(fd, iov, cnt);
7453 Py_END_ALLOW_THREADS
7454
7455 iov_cleanup(iov, buf, cnt);
7456 return PyLong_FromSsize_t(n);
7457}
7458#endif
7459
7460#ifdef HAVE_PREAD
7461PyDoc_STRVAR(posix_pread__doc__,
7462"pread(fd, buffersize, offset) -> string\n\n\
7463Read from a file descriptor, fd, at a position of offset. It will read up\n\
7464to buffersize number of bytes. The file offset remains unchanged.");
7465
7466static PyObject *
7467posix_pread(PyObject *self, PyObject *args)
7468{
7469 int fd, size;
7470 off_t offset;
7471 Py_ssize_t n;
7472 PyObject *buffer;
7473 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7474 return NULL;
7475
7476 if (size < 0) {
7477 errno = EINVAL;
7478 return posix_error();
7479 }
7480 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7481 if (buffer == NULL)
7482 return NULL;
7483 if (!_PyVerify_fd(fd)) {
7484 Py_DECREF(buffer);
7485 return posix_error();
7486 }
7487 Py_BEGIN_ALLOW_THREADS
7488 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7489 Py_END_ALLOW_THREADS
7490 if (n < 0) {
7491 Py_DECREF(buffer);
7492 return posix_error();
7493 }
7494 if (n != size)
7495 _PyBytes_Resize(&buffer, n);
7496 return buffer;
7497}
7498#endif
7499
7500PyDoc_STRVAR(posix_write__doc__,
7501"write(fd, string) -> byteswritten\n\n\
7502Write a string to a file descriptor.");
7503
7504static PyObject *
7505posix_write(PyObject *self, PyObject *args)
7506{
7507 Py_buffer pbuf;
7508 int fd;
7509 Py_ssize_t size, len;
7510
7511 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
7512 return NULL;
7513 if (!_PyVerify_fd(fd)) {
7514 PyBuffer_Release(&pbuf);
7515 return posix_error();
7516 }
7517 len = pbuf.len;
7518 Py_BEGIN_ALLOW_THREADS
7519#if defined(MS_WIN64) || defined(MS_WINDOWS)
7520 if (len > INT_MAX)
7521 len = INT_MAX;
7522 size = write(fd, pbuf.buf, (int)len);
7523#else
7524 size = write(fd, pbuf.buf, len);
7525#endif
7526 Py_END_ALLOW_THREADS
7527 PyBuffer_Release(&pbuf);
7528 if (size < 0)
7529 return posix_error();
7530 return PyLong_FromSsize_t(size);
7531}
7532
7533#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007534PyDoc_STRVAR(posix_sendfile__doc__,
7535"sendfile(out, in, offset, nbytes) -> byteswritten\n\
7536sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
7537 -> byteswritten\n\
7538Copy nbytes bytes from file descriptor in to file descriptor out.");
7539
7540static PyObject *
7541posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
7542{
7543 int in, out;
7544 Py_ssize_t ret;
7545 off_t offset;
7546
7547#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
7548#ifndef __APPLE__
7549 Py_ssize_t len;
7550#endif
7551 PyObject *headers = NULL, *trailers = NULL;
7552 Py_buffer *hbuf, *tbuf;
7553 off_t sbytes;
7554 struct sf_hdtr sf;
7555 int flags = 0;
7556 sf.headers = NULL;
7557 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00007558 static char *keywords[] = {"out", "in",
7559 "offset", "count",
7560 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007561
7562#ifdef __APPLE__
7563 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007564 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007565#else
7566 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007567 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007568#endif
7569 &headers, &trailers, &flags))
7570 return NULL;
7571 if (headers != NULL) {
7572 if (!PySequence_Check(headers)) {
7573 PyErr_SetString(PyExc_TypeError,
7574 "sendfile() headers must be a sequence or None");
7575 return NULL;
7576 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007577 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007578 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007579 if (sf.hdr_cnt > 0 &&
7580 !(i = iov_setup(&(sf.headers), &hbuf,
7581 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007582 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007583#ifdef __APPLE__
7584 sbytes += i;
7585#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007586 }
7587 }
7588 if (trailers != NULL) {
7589 if (!PySequence_Check(trailers)) {
7590 PyErr_SetString(PyExc_TypeError,
7591 "sendfile() trailers must be a sequence or None");
7592 return NULL;
7593 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007594 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007595 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007596 if (sf.trl_cnt > 0 &&
7597 !(i = iov_setup(&(sf.trailers), &tbuf,
7598 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007599 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007600#ifdef __APPLE__
7601 sbytes += i;
7602#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007603 }
7604 }
7605
7606 Py_BEGIN_ALLOW_THREADS
7607#ifdef __APPLE__
7608 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
7609#else
7610 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
7611#endif
7612 Py_END_ALLOW_THREADS
7613
7614 if (sf.headers != NULL)
7615 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
7616 if (sf.trailers != NULL)
7617 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
7618
7619 if (ret < 0) {
7620 if ((errno == EAGAIN) || (errno == EBUSY)) {
7621 if (sbytes != 0) {
7622 // some data has been sent
7623 goto done;
7624 }
7625 else {
7626 // no data has been sent; upper application is supposed
7627 // to retry on EAGAIN or EBUSY
7628 return posix_error();
7629 }
7630 }
7631 return posix_error();
7632 }
7633 goto done;
7634
7635done:
7636 #if !defined(HAVE_LARGEFILE_SUPPORT)
7637 return Py_BuildValue("l", sbytes);
7638 #else
7639 return Py_BuildValue("L", sbytes);
7640 #endif
7641
7642#else
7643 Py_ssize_t count;
7644 PyObject *offobj;
7645 static char *keywords[] = {"out", "in",
7646 "offset", "count", NULL};
7647 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
7648 keywords, &out, &in, &offobj, &count))
7649 return NULL;
7650#ifdef linux
7651 if (offobj == Py_None) {
7652 Py_BEGIN_ALLOW_THREADS
7653 ret = sendfile(out, in, NULL, count);
7654 Py_END_ALLOW_THREADS
7655 if (ret < 0)
7656 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02007657 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007658 }
7659#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00007660 if (!_parse_off_t(offobj, &offset))
7661 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007662 Py_BEGIN_ALLOW_THREADS
7663 ret = sendfile(out, in, &offset, count);
7664 Py_END_ALLOW_THREADS
7665 if (ret < 0)
7666 return posix_error();
7667 return Py_BuildValue("n", ret);
7668#endif
7669}
7670#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007671
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007672PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007673"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07007674Like stat(), but for an open file descriptor.\n\
7675Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007676
Barry Warsaw53699e91996-12-10 23:23:01 +00007677static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007678posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007679{
Victor Stinner8c62be82010-05-06 00:08:46 +00007680 int fd;
7681 STRUCT_STAT st;
7682 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01007683 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007684 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007685#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00007686 /* on OpenVMS we must ensure that all bytes are written to the file */
7687 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007688#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007689 Py_BEGIN_ALLOW_THREADS
7690 res = FSTAT(fd, &st);
7691 Py_END_ALLOW_THREADS
7692 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00007693#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01007694 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00007695#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007696 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00007697#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007698 }
Tim Peters5aa91602002-01-30 05:46:57 +00007699
Victor Stinner4195b5c2012-02-08 23:03:19 +01007700 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00007701}
7702
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007703PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007704"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007705Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007706connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00007707
7708static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00007709posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00007710{
Victor Stinner8c62be82010-05-06 00:08:46 +00007711 int fd;
7712 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
7713 return NULL;
7714 if (!_PyVerify_fd(fd))
7715 return PyBool_FromLong(0);
7716 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00007717}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007718
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007719#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007720PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007721"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007722Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007723
Barry Warsaw53699e91996-12-10 23:23:01 +00007724static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007725posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007726{
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007727#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007728 int fds[2];
7729 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007730 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00007731 if (res != 0)
7732 return posix_error();
7733 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007734#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007735 HANDLE read, write;
7736 int read_fd, write_fd;
7737 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00007738 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00007739 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01007740 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00007741 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
7742 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
7743 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007744#endif /* MS_WINDOWS */
Guido van Rossum687dd131993-05-17 08:34:16 +00007745}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007746#endif /* HAVE_PIPE */
7747
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007748#ifdef HAVE_PIPE2
7749PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02007750"pipe2(flags) -> (read_end, write_end)\n\n\
7751Create a pipe with flags set atomically.\n\
7752flags can be constructed by ORing together one or more of these values:\n\
7753O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007754");
7755
7756static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02007757posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007758{
Charles-François Natali368f34b2011-06-06 19:49:47 +02007759 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007760 int fds[2];
7761 int res;
7762
Serhiy Storchaka78980432013-01-15 01:12:17 +02007763 flags = _PyLong_AsInt(arg);
Charles-François Natali368f34b2011-06-06 19:49:47 +02007764 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007765 return NULL;
7766
7767 res = pipe2(fds, flags);
7768 if (res != 0)
7769 return posix_error();
7770 return Py_BuildValue("(ii)", fds[0], fds[1]);
7771}
7772#endif /* HAVE_PIPE2 */
7773
Ross Lagerwall7807c352011-03-17 20:20:30 +02007774#ifdef HAVE_WRITEV
7775PyDoc_STRVAR(posix_writev__doc__,
7776"writev(fd, buffers) -> byteswritten\n\n\
7777Write the contents of buffers to a file descriptor, where buffers is an\n\
7778arbitrary sequence of buffers.\n\
7779Returns the total bytes written.");
7780
7781static PyObject *
7782posix_writev(PyObject *self, PyObject *args)
7783{
7784 int fd, cnt;
7785 Py_ssize_t res;
7786 PyObject *seq;
7787 struct iovec *iov;
7788 Py_buffer *buf;
7789 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
7790 return NULL;
7791 if (!PySequence_Check(seq)) {
7792 PyErr_SetString(PyExc_TypeError,
7793 "writev() arg 2 must be a sequence");
7794 return NULL;
7795 }
7796 cnt = PySequence_Size(seq);
7797
7798 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
7799 return NULL;
7800 }
7801
7802 Py_BEGIN_ALLOW_THREADS
7803 res = writev(fd, iov, cnt);
7804 Py_END_ALLOW_THREADS
7805
7806 iov_cleanup(iov, buf, cnt);
7807 return PyLong_FromSsize_t(res);
7808}
7809#endif
7810
7811#ifdef HAVE_PWRITE
7812PyDoc_STRVAR(posix_pwrite__doc__,
7813"pwrite(fd, string, offset) -> byteswritten\n\n\
7814Write string to a file descriptor, fd, from offset, leaving the file\n\
7815offset unchanged.");
7816
7817static PyObject *
7818posix_pwrite(PyObject *self, PyObject *args)
7819{
7820 Py_buffer pbuf;
7821 int fd;
7822 off_t offset;
7823 Py_ssize_t size;
7824
7825 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
7826 return NULL;
7827
7828 if (!_PyVerify_fd(fd)) {
7829 PyBuffer_Release(&pbuf);
7830 return posix_error();
7831 }
7832 Py_BEGIN_ALLOW_THREADS
7833 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
7834 Py_END_ALLOW_THREADS
7835 PyBuffer_Release(&pbuf);
7836 if (size < 0)
7837 return posix_error();
7838 return PyLong_FromSsize_t(size);
7839}
7840#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007841
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007842#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007843PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007844"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
7845Create a FIFO (a POSIX named pipe).\n\
7846\n\
7847If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7848 and path should be relative; path will then be relative to that directory.\n\
7849dir_fd may not be implemented on your platform.\n\
7850 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007851
Barry Warsaw53699e91996-12-10 23:23:01 +00007852static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007853posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007854{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007855 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00007856 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007857 int dir_fd = DEFAULT_DIR_FD;
7858 int result;
7859 PyObject *return_value = NULL;
7860 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
7861
7862 memset(&path, 0, sizeof(path));
7863 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
7864 path_converter, &path,
7865 &mode,
7866#ifdef HAVE_MKFIFOAT
7867 dir_fd_converter, &dir_fd
7868#else
7869 dir_fd_unavailable, &dir_fd
7870#endif
7871 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007872 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007873
Victor Stinner8c62be82010-05-06 00:08:46 +00007874 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007875#ifdef HAVE_MKFIFOAT
7876 if (dir_fd != DEFAULT_DIR_FD)
7877 result = mkfifoat(dir_fd, path.narrow, mode);
7878 else
7879#endif
7880 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007881 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007882
7883 if (result < 0) {
7884 return_value = posix_error();
7885 goto exit;
7886 }
7887
7888 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00007889 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007890
7891exit:
7892 path_cleanup(&path);
7893 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007894}
7895#endif
7896
Neal Norwitz11690112002-07-30 01:08:28 +00007897#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007898PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007899"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007900Create a filesystem node (file, device special file or named pipe)\n\
7901named filename. mode specifies both the permissions to use and the\n\
7902type of node to be created, being combined (bitwise OR) with one of\n\
7903S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007904device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07007905os.makedev()), otherwise it is ignored.\n\
7906\n\
7907If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7908 and path should be relative; path will then be relative to that directory.\n\
7909dir_fd may not be implemented on your platform.\n\
7910 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007911
7912
7913static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007914posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007915{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007916 path_t path;
7917 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00007918 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007919 int dir_fd = DEFAULT_DIR_FD;
7920 int result;
7921 PyObject *return_value = NULL;
7922 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
7923
7924 memset(&path, 0, sizeof(path));
7925 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
7926 path_converter, &path,
7927 &mode, &device,
7928#ifdef HAVE_MKNODAT
7929 dir_fd_converter, &dir_fd
7930#else
7931 dir_fd_unavailable, &dir_fd
7932#endif
7933 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007934 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007935
Victor Stinner8c62be82010-05-06 00:08:46 +00007936 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007937#ifdef HAVE_MKNODAT
7938 if (dir_fd != DEFAULT_DIR_FD)
7939 result = mknodat(dir_fd, path.narrow, mode, device);
7940 else
7941#endif
7942 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00007943 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007944
7945 if (result < 0) {
7946 return_value = posix_error();
7947 goto exit;
7948 }
7949
7950 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00007951 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02007952
Larry Hastings9cf065c2012-06-22 16:30:09 -07007953exit:
7954 path_cleanup(&path);
7955 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007956}
7957#endif
7958
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007959#ifdef HAVE_DEVICE_MACROS
7960PyDoc_STRVAR(posix_major__doc__,
7961"major(device) -> major number\n\
7962Extracts a device major number from a raw device number.");
7963
7964static PyObject *
7965posix_major(PyObject *self, PyObject *args)
7966{
Victor Stinner8c62be82010-05-06 00:08:46 +00007967 int device;
7968 if (!PyArg_ParseTuple(args, "i:major", &device))
7969 return NULL;
7970 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007971}
7972
7973PyDoc_STRVAR(posix_minor__doc__,
7974"minor(device) -> minor number\n\
7975Extracts a device minor number from a raw device number.");
7976
7977static PyObject *
7978posix_minor(PyObject *self, PyObject *args)
7979{
Victor Stinner8c62be82010-05-06 00:08:46 +00007980 int device;
7981 if (!PyArg_ParseTuple(args, "i:minor", &device))
7982 return NULL;
7983 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007984}
7985
7986PyDoc_STRVAR(posix_makedev__doc__,
7987"makedev(major, minor) -> device number\n\
7988Composes a raw device number from the major and minor device numbers.");
7989
7990static PyObject *
7991posix_makedev(PyObject *self, PyObject *args)
7992{
Victor Stinner8c62be82010-05-06 00:08:46 +00007993 int major, minor;
7994 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
7995 return NULL;
7996 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007997}
7998#endif /* device macros */
7999
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008000
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008001#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008002PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008003"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008004Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008005
Barry Warsaw53699e91996-12-10 23:23:01 +00008006static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008007posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008008{
Victor Stinner8c62be82010-05-06 00:08:46 +00008009 int fd;
8010 off_t length;
8011 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008012
Ross Lagerwall7807c352011-03-17 20:20:30 +02008013 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008014 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008015
Victor Stinner8c62be82010-05-06 00:08:46 +00008016 Py_BEGIN_ALLOW_THREADS
8017 res = ftruncate(fd, length);
8018 Py_END_ALLOW_THREADS
8019 if (res < 0)
8020 return posix_error();
8021 Py_INCREF(Py_None);
8022 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008023}
8024#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008025
Ross Lagerwall7807c352011-03-17 20:20:30 +02008026#ifdef HAVE_TRUNCATE
8027PyDoc_STRVAR(posix_truncate__doc__,
8028"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008029Truncate the file given by path to length bytes.\n\
8030On some platforms, path may also be specified as an open file descriptor.\n\
8031 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008032
8033static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008034posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008035{
Georg Brandl306336b2012-06-24 12:55:33 +02008036 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008037 off_t length;
8038 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008039 PyObject *result = NULL;
8040 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008041
Georg Brandl306336b2012-06-24 12:55:33 +02008042 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008043 path.function_name = "truncate";
Georg Brandl306336b2012-06-24 12:55:33 +02008044#ifdef HAVE_FTRUNCATE
8045 path.allow_fd = 1;
8046#endif
8047 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8048 path_converter, &path,
8049 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008050 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008051
8052 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008053#ifdef HAVE_FTRUNCATE
8054 if (path.fd != -1)
8055 res = ftruncate(path.fd, length);
8056 else
8057#endif
8058 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008059 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008060 if (res < 0)
Victor Stinner292c8352012-10-30 02:17:38 +01008061 result = path_error(&path);
Georg Brandl306336b2012-06-24 12:55:33 +02008062 else {
8063 Py_INCREF(Py_None);
8064 result = Py_None;
8065 }
8066 path_cleanup(&path);
8067 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008068}
8069#endif
8070
8071#ifdef HAVE_POSIX_FALLOCATE
8072PyDoc_STRVAR(posix_posix_fallocate__doc__,
8073"posix_fallocate(fd, offset, len)\n\n\
8074Ensures that enough disk space is allocated for the file specified by fd\n\
8075starting from offset and continuing for len bytes.");
8076
8077static PyObject *
8078posix_posix_fallocate(PyObject *self, PyObject *args)
8079{
8080 off_t len, offset;
8081 int res, fd;
8082
8083 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8084 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8085 return NULL;
8086
8087 Py_BEGIN_ALLOW_THREADS
8088 res = posix_fallocate(fd, offset, len);
8089 Py_END_ALLOW_THREADS
8090 if (res != 0) {
8091 errno = res;
8092 return posix_error();
8093 }
8094 Py_RETURN_NONE;
8095}
8096#endif
8097
8098#ifdef HAVE_POSIX_FADVISE
8099PyDoc_STRVAR(posix_posix_fadvise__doc__,
8100"posix_fadvise(fd, offset, len, advice)\n\n\
8101Announces an intention to access data in a specific pattern thus allowing\n\
8102the kernel to make optimizations.\n\
8103The advice applies to the region of the file specified by fd starting at\n\
8104offset and continuing for len bytes.\n\
8105advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8106POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8107POSIX_FADV_DONTNEED.");
8108
8109static PyObject *
8110posix_posix_fadvise(PyObject *self, PyObject *args)
8111{
8112 off_t len, offset;
8113 int res, fd, advice;
8114
8115 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8116 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8117 return NULL;
8118
8119 Py_BEGIN_ALLOW_THREADS
8120 res = posix_fadvise(fd, offset, len, advice);
8121 Py_END_ALLOW_THREADS
8122 if (res != 0) {
8123 errno = res;
8124 return posix_error();
8125 }
8126 Py_RETURN_NONE;
8127}
8128#endif
8129
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008130#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008131PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008132"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008133Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008134
Fred Drake762e2061999-08-26 17:23:54 +00008135/* Save putenv() parameters as values here, so we can collect them when they
8136 * get re-set with another call for the same key. */
8137static PyObject *posix_putenv_garbage;
8138
Tim Peters5aa91602002-01-30 05:46:57 +00008139static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008140posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008141{
Victor Stinner84ae1182010-05-06 22:05:07 +00008142 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008143#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008144 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008145 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008146
Victor Stinner8c62be82010-05-06 00:08:46 +00008147 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008148 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008149 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008150 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008151
Victor Stinner65170952011-11-22 22:16:17 +01008152 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008153 if (newstr == NULL) {
8154 PyErr_NoMemory();
8155 goto error;
8156 }
Victor Stinner65170952011-11-22 22:16:17 +01008157 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8158 PyErr_Format(PyExc_ValueError,
8159 "the environment variable is longer than %u characters",
8160 _MAX_ENV);
8161 goto error;
8162 }
8163
Victor Stinner8c62be82010-05-06 00:08:46 +00008164 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008165 if (newenv == NULL)
8166 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008167 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008168 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008169 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008170 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008171#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008172 PyObject *os1, *os2;
8173 char *s1, *s2;
8174 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008175
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008176 if (!PyArg_ParseTuple(args,
8177 "O&O&:putenv",
8178 PyUnicode_FSConverter, &os1,
8179 PyUnicode_FSConverter, &os2))
8180 return NULL;
8181 s1 = PyBytes_AsString(os1);
8182 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008183
Victor Stinner65170952011-11-22 22:16:17 +01008184 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008185 if (newstr == NULL) {
8186 PyErr_NoMemory();
8187 goto error;
8188 }
8189
Victor Stinner8c62be82010-05-06 00:08:46 +00008190 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008191 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008192 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008193 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008194 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008195#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008196
Victor Stinner8c62be82010-05-06 00:08:46 +00008197 /* Install the first arg and newstr in posix_putenv_garbage;
8198 * this will cause previous value to be collected. This has to
8199 * happen after the real putenv() call because the old value
8200 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008201 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008202 /* really not much we can do; just leak */
8203 PyErr_Clear();
8204 }
8205 else {
8206 Py_DECREF(newstr);
8207 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008208
Martin v. Löwis011e8422009-05-05 04:43:17 +00008209#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008210 Py_DECREF(os1);
8211 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008212#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008213 Py_RETURN_NONE;
8214
8215error:
8216#ifndef MS_WINDOWS
8217 Py_DECREF(os1);
8218 Py_DECREF(os2);
8219#endif
8220 Py_XDECREF(newstr);
8221 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008222}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008223#endif /* putenv */
8224
Guido van Rossumc524d952001-10-19 01:31:59 +00008225#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008226PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008227"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008228Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008229
8230static PyObject *
8231posix_unsetenv(PyObject *self, PyObject *args)
8232{
Victor Stinner65170952011-11-22 22:16:17 +01008233 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008234#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008235 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008236#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008237
8238 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008239
Victor Stinner65170952011-11-22 22:16:17 +01008240 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008241 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008242
Victor Stinner984890f2011-11-24 13:53:38 +01008243#ifdef HAVE_BROKEN_UNSETENV
8244 unsetenv(PyBytes_AS_STRING(name));
8245#else
Victor Stinner65170952011-11-22 22:16:17 +01008246 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008247 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008248 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008249 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008250 }
Victor Stinner984890f2011-11-24 13:53:38 +01008251#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008252
Victor Stinner8c62be82010-05-06 00:08:46 +00008253 /* Remove the key from posix_putenv_garbage;
8254 * this will cause it to be collected. This has to
8255 * happen after the real unsetenv() call because the
8256 * old value was still accessible until then.
8257 */
Victor Stinner65170952011-11-22 22:16:17 +01008258 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008259 /* really not much we can do; just leak */
8260 PyErr_Clear();
8261 }
Victor Stinner65170952011-11-22 22:16:17 +01008262 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008263 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008264}
8265#endif /* unsetenv */
8266
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008267PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008268"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008269Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008270
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008271static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008272posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008273{
Victor Stinner8c62be82010-05-06 00:08:46 +00008274 int code;
8275 char *message;
8276 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8277 return NULL;
8278 message = strerror(code);
8279 if (message == NULL) {
8280 PyErr_SetString(PyExc_ValueError,
8281 "strerror() argument out of range");
8282 return NULL;
8283 }
Victor Stinner1b579672011-12-17 05:47:23 +01008284 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008285}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008286
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008287
Guido van Rossumc9641791998-08-04 15:26:23 +00008288#ifdef HAVE_SYS_WAIT_H
8289
Fred Drake106c1a02002-04-23 15:58:02 +00008290#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008291PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008292"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008293Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008294
8295static PyObject *
8296posix_WCOREDUMP(PyObject *self, PyObject *args)
8297{
Victor Stinner8c62be82010-05-06 00:08:46 +00008298 WAIT_TYPE status;
8299 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008300
Victor Stinner8c62be82010-05-06 00:08:46 +00008301 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8302 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008303
Victor Stinner8c62be82010-05-06 00:08:46 +00008304 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008305}
8306#endif /* WCOREDUMP */
8307
8308#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008309PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008310"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008311Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008312job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00008313
8314static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008315posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00008316{
Victor Stinner8c62be82010-05-06 00:08:46 +00008317 WAIT_TYPE status;
8318 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008319
Victor Stinner8c62be82010-05-06 00:08:46 +00008320 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
8321 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008322
Victor Stinner8c62be82010-05-06 00:08:46 +00008323 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008324}
8325#endif /* WIFCONTINUED */
8326
Guido van Rossumc9641791998-08-04 15:26:23 +00008327#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008328PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008329"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008330Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008331
8332static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008333posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008334{
Victor Stinner8c62be82010-05-06 00:08:46 +00008335 WAIT_TYPE status;
8336 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008337
Victor Stinner8c62be82010-05-06 00:08:46 +00008338 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
8339 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008340
Victor Stinner8c62be82010-05-06 00:08:46 +00008341 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008342}
8343#endif /* WIFSTOPPED */
8344
8345#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008346PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008347"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008348Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008349
8350static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008351posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008352{
Victor Stinner8c62be82010-05-06 00:08:46 +00008353 WAIT_TYPE status;
8354 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008355
Victor Stinner8c62be82010-05-06 00:08:46 +00008356 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8357 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008358
Victor Stinner8c62be82010-05-06 00:08:46 +00008359 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008360}
8361#endif /* WIFSIGNALED */
8362
8363#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008364PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008365"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008366Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008367system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008368
8369static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008370posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008371{
Victor Stinner8c62be82010-05-06 00:08:46 +00008372 WAIT_TYPE status;
8373 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008374
Victor Stinner8c62be82010-05-06 00:08:46 +00008375 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
8376 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008377
Victor Stinner8c62be82010-05-06 00:08:46 +00008378 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008379}
8380#endif /* WIFEXITED */
8381
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008382#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008383PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008384"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008385Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008386
8387static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008388posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008389{
Victor Stinner8c62be82010-05-06 00:08:46 +00008390 WAIT_TYPE status;
8391 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008392
Victor Stinner8c62be82010-05-06 00:08:46 +00008393 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8394 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008395
Victor Stinner8c62be82010-05-06 00:08:46 +00008396 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008397}
8398#endif /* WEXITSTATUS */
8399
8400#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008401PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008402"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008403Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008404value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008405
8406static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008407posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008408{
Victor Stinner8c62be82010-05-06 00:08:46 +00008409 WAIT_TYPE status;
8410 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008411
Victor Stinner8c62be82010-05-06 00:08:46 +00008412 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8413 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008414
Victor Stinner8c62be82010-05-06 00:08:46 +00008415 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008416}
8417#endif /* WTERMSIG */
8418
8419#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008420PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008421"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008422Return the signal that stopped the process that provided\n\
8423the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008424
8425static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008426posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008427{
Victor Stinner8c62be82010-05-06 00:08:46 +00008428 WAIT_TYPE status;
8429 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008430
Victor Stinner8c62be82010-05-06 00:08:46 +00008431 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8432 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008433
Victor Stinner8c62be82010-05-06 00:08:46 +00008434 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008435}
8436#endif /* WSTOPSIG */
8437
8438#endif /* HAVE_SYS_WAIT_H */
8439
8440
Thomas Wouters477c8d52006-05-27 19:21:47 +00008441#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00008442#ifdef _SCO_DS
8443/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
8444 needed definitions in sys/statvfs.h */
8445#define _SVID3
8446#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008447#include <sys/statvfs.h>
8448
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008449static PyObject*
8450_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008451 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8452 if (v == NULL)
8453 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008454
8455#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008456 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8457 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8458 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8459 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8460 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8461 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8462 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8463 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8464 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8465 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008466#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008467 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8468 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8469 PyStructSequence_SET_ITEM(v, 2,
8470 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8471 PyStructSequence_SET_ITEM(v, 3,
8472 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8473 PyStructSequence_SET_ITEM(v, 4,
8474 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8475 PyStructSequence_SET_ITEM(v, 5,
8476 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8477 PyStructSequence_SET_ITEM(v, 6,
8478 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8479 PyStructSequence_SET_ITEM(v, 7,
8480 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
8481 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8482 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008483#endif
8484
Victor Stinner8c62be82010-05-06 00:08:46 +00008485 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008486}
8487
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008488PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008489"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008490Perform an fstatvfs system call on the given fd.\n\
8491Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008492
8493static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008494posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008495{
Victor Stinner8c62be82010-05-06 00:08:46 +00008496 int fd, res;
8497 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008498
Victor Stinner8c62be82010-05-06 00:08:46 +00008499 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
8500 return NULL;
8501 Py_BEGIN_ALLOW_THREADS
8502 res = fstatvfs(fd, &st);
8503 Py_END_ALLOW_THREADS
8504 if (res != 0)
8505 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008506
Victor Stinner8c62be82010-05-06 00:08:46 +00008507 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008508}
Thomas Wouters477c8d52006-05-27 19:21:47 +00008509#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008510
8511
Thomas Wouters477c8d52006-05-27 19:21:47 +00008512#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008513#include <sys/statvfs.h>
8514
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008515PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008516"statvfs(path)\n\n\
8517Perform a statvfs system call on the given path.\n\
8518\n\
8519path may always be specified as a string.\n\
8520On some platforms, path may also be specified as an open file descriptor.\n\
8521 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008522
8523static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008524posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008525{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008526 static char *keywords[] = {"path", NULL};
8527 path_t path;
8528 int result;
8529 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008530 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008531
Larry Hastings9cf065c2012-06-22 16:30:09 -07008532 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008533 path.function_name = "statvfs";
Larry Hastings9cf065c2012-06-22 16:30:09 -07008534#ifdef HAVE_FSTATVFS
8535 path.allow_fd = 1;
8536#endif
8537 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
8538 path_converter, &path
8539 ))
8540 return NULL;
8541
8542 Py_BEGIN_ALLOW_THREADS
8543#ifdef HAVE_FSTATVFS
8544 if (path.fd != -1) {
8545#ifdef __APPLE__
8546 /* handle weak-linking on Mac OS X 10.3 */
8547 if (fstatvfs == NULL) {
8548 fd_specified("statvfs", path.fd);
8549 goto exit;
8550 }
8551#endif
8552 result = fstatvfs(path.fd, &st);
8553 }
8554 else
8555#endif
8556 result = statvfs(path.narrow, &st);
8557 Py_END_ALLOW_THREADS
8558
8559 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01008560 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008561 goto exit;
8562 }
8563
8564 return_value = _pystatvfs_fromstructstatvfs(st);
8565
8566exit:
8567 path_cleanup(&path);
8568 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00008569}
8570#endif /* HAVE_STATVFS */
8571
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008572#ifdef MS_WINDOWS
8573PyDoc_STRVAR(win32__getdiskusage__doc__,
8574"_getdiskusage(path) -> (total, free)\n\n\
8575Return disk usage statistics about the given path as (total, free) tuple.");
8576
8577static PyObject *
8578win32__getdiskusage(PyObject *self, PyObject *args)
8579{
8580 BOOL retval;
8581 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01008582 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008583
Victor Stinner6139c1b2011-11-09 22:14:14 +01008584 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008585 return NULL;
8586
8587 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01008588 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008589 Py_END_ALLOW_THREADS
8590 if (retval == 0)
8591 return PyErr_SetFromWindowsErr(0);
8592
8593 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
8594}
8595#endif
8596
8597
Fred Drakec9680921999-12-13 16:37:25 +00008598/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
8599 * It maps strings representing configuration variable names to
8600 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00008601 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00008602 * rarely-used constants. There are three separate tables that use
8603 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00008604 *
8605 * This code is always included, even if none of the interfaces that
8606 * need it are included. The #if hackery needed to avoid it would be
8607 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00008608 */
8609struct constdef {
8610 char *name;
8611 long value;
8612};
8613
Fred Drake12c6e2d1999-12-14 21:25:03 +00008614static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008615conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00008616 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00008617{
Christian Heimes217cfd12007-12-02 14:31:20 +00008618 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008619 *valuep = PyLong_AS_LONG(arg);
8620 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00008621 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00008622 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00008623 /* look up the value in the table using a binary search */
8624 size_t lo = 0;
8625 size_t mid;
8626 size_t hi = tablesize;
8627 int cmp;
8628 const char *confname;
8629 if (!PyUnicode_Check(arg)) {
8630 PyErr_SetString(PyExc_TypeError,
8631 "configuration names must be strings or integers");
8632 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008633 }
Stefan Krah0e803b32010-11-26 16:16:47 +00008634 confname = _PyUnicode_AsString(arg);
8635 if (confname == NULL)
8636 return 0;
8637 while (lo < hi) {
8638 mid = (lo + hi) / 2;
8639 cmp = strcmp(confname, table[mid].name);
8640 if (cmp < 0)
8641 hi = mid;
8642 else if (cmp > 0)
8643 lo = mid + 1;
8644 else {
8645 *valuep = table[mid].value;
8646 return 1;
8647 }
8648 }
8649 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
8650 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008651 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00008652}
8653
8654
8655#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
8656static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008657#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008658 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008659#endif
8660#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008661 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008662#endif
Fred Drakec9680921999-12-13 16:37:25 +00008663#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008664 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008665#endif
8666#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00008667 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00008668#endif
8669#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00008670 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00008671#endif
8672#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00008673 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00008674#endif
8675#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008676 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008677#endif
8678#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00008679 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00008680#endif
8681#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008682 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00008683#endif
8684#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008685 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008686#endif
8687#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008688 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00008689#endif
8690#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008691 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008692#endif
8693#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008694 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00008695#endif
8696#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008697 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008698#endif
8699#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008700 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00008701#endif
8702#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008703 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008704#endif
8705#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008706 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00008707#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00008708#ifdef _PC_ACL_ENABLED
8709 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
8710#endif
8711#ifdef _PC_MIN_HOLE_SIZE
8712 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
8713#endif
8714#ifdef _PC_ALLOC_SIZE_MIN
8715 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
8716#endif
8717#ifdef _PC_REC_INCR_XFER_SIZE
8718 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
8719#endif
8720#ifdef _PC_REC_MAX_XFER_SIZE
8721 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
8722#endif
8723#ifdef _PC_REC_MIN_XFER_SIZE
8724 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
8725#endif
8726#ifdef _PC_REC_XFER_ALIGN
8727 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
8728#endif
8729#ifdef _PC_SYMLINK_MAX
8730 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
8731#endif
8732#ifdef _PC_XATTR_ENABLED
8733 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
8734#endif
8735#ifdef _PC_XATTR_EXISTS
8736 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
8737#endif
8738#ifdef _PC_TIMESTAMP_RESOLUTION
8739 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
8740#endif
Fred Drakec9680921999-12-13 16:37:25 +00008741};
8742
Fred Drakec9680921999-12-13 16:37:25 +00008743static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008744conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008745{
8746 return conv_confname(arg, valuep, posix_constants_pathconf,
8747 sizeof(posix_constants_pathconf)
8748 / sizeof(struct constdef));
8749}
8750#endif
8751
8752#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008753PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008754"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008755Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008756If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00008757
8758static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008759posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008760{
8761 PyObject *result = NULL;
8762 int name, fd;
8763
Fred Drake12c6e2d1999-12-14 21:25:03 +00008764 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
8765 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008766 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008767
Stefan Krah0e803b32010-11-26 16:16:47 +00008768 errno = 0;
8769 limit = fpathconf(fd, name);
8770 if (limit == -1 && errno != 0)
8771 posix_error();
8772 else
8773 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008774 }
8775 return result;
8776}
8777#endif
8778
8779
8780#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008781PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008782"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008783Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008784If there is no limit, return -1.\n\
8785On some platforms, path may also be specified as an open file descriptor.\n\
8786 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00008787
8788static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008789posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00008790{
Georg Brandl306336b2012-06-24 12:55:33 +02008791 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00008792 PyObject *result = NULL;
8793 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02008794 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00008795
Georg Brandl306336b2012-06-24 12:55:33 +02008796 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008797 path.function_name = "pathconf";
Georg Brandl306336b2012-06-24 12:55:33 +02008798#ifdef HAVE_FPATHCONF
8799 path.allow_fd = 1;
8800#endif
8801 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
8802 path_converter, &path,
8803 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008804 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008805
Victor Stinner8c62be82010-05-06 00:08:46 +00008806 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02008807#ifdef HAVE_FPATHCONF
8808 if (path.fd != -1)
8809 limit = fpathconf(path.fd, name);
8810 else
8811#endif
8812 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00008813 if (limit == -1 && errno != 0) {
8814 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00008815 /* could be a path or name problem */
8816 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00008817 else
Victor Stinner292c8352012-10-30 02:17:38 +01008818 result = path_error(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00008819 }
8820 else
8821 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008822 }
Georg Brandl306336b2012-06-24 12:55:33 +02008823 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00008824 return result;
8825}
8826#endif
8827
8828#ifdef HAVE_CONFSTR
8829static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008830#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00008831 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00008832#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00008833#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008834 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008835#endif
8836#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008837 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008838#endif
Fred Draked86ed291999-12-15 15:34:33 +00008839#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008840 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008841#endif
8842#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008843 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008844#endif
8845#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008846 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008847#endif
8848#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008849 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008850#endif
Fred Drakec9680921999-12-13 16:37:25 +00008851#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008852 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008853#endif
8854#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008855 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008856#endif
8857#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008858 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008859#endif
8860#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008861 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008862#endif
8863#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008864 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008865#endif
8866#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008867 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008868#endif
8869#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008870 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008871#endif
8872#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008873 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008874#endif
Fred Draked86ed291999-12-15 15:34:33 +00008875#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00008876 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00008877#endif
Fred Drakec9680921999-12-13 16:37:25 +00008878#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00008879 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00008880#endif
Fred Draked86ed291999-12-15 15:34:33 +00008881#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008882 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00008883#endif
8884#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008885 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00008886#endif
8887#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008888 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008889#endif
8890#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008891 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00008892#endif
Fred Drakec9680921999-12-13 16:37:25 +00008893#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008894 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008895#endif
8896#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008897 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008898#endif
8899#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008900 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008901#endif
8902#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008903 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008904#endif
8905#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008906 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008907#endif
8908#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008909 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008910#endif
8911#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008912 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008913#endif
8914#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008915 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008916#endif
8917#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008918 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008919#endif
8920#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008921 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008922#endif
8923#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008924 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008925#endif
8926#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008927 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008928#endif
8929#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008930 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008931#endif
8932#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008933 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008934#endif
8935#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008936 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008937#endif
8938#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008939 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008940#endif
Fred Draked86ed291999-12-15 15:34:33 +00008941#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008942 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008943#endif
8944#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008945 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00008946#endif
8947#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00008948 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00008949#endif
8950#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008951 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008952#endif
8953#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008954 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008955#endif
8956#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00008957 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00008958#endif
8959#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008960 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00008961#endif
8962#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00008963 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00008964#endif
8965#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008966 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008967#endif
8968#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008969 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008970#endif
8971#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008972 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008973#endif
8974#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008975 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008976#endif
8977#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00008978 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00008979#endif
Fred Drakec9680921999-12-13 16:37:25 +00008980};
8981
8982static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008983conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008984{
8985 return conv_confname(arg, valuep, posix_constants_confstr,
8986 sizeof(posix_constants_confstr)
8987 / sizeof(struct constdef));
8988}
8989
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008990PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008991"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008992Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008993
8994static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008995posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008996{
8997 PyObject *result = NULL;
8998 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00008999 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00009000 int len;
Fred Drakec9680921999-12-13 16:37:25 +00009001
Victor Stinnercb043522010-09-10 23:49:04 +00009002 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9003 return NULL;
9004
9005 errno = 0;
9006 len = confstr(name, buffer, sizeof(buffer));
9007 if (len == 0) {
9008 if (errno) {
9009 posix_error();
9010 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009011 }
9012 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009013 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009014 }
9015 }
Victor Stinnercb043522010-09-10 23:49:04 +00009016
9017 if ((unsigned int)len >= sizeof(buffer)) {
9018 char *buf = PyMem_Malloc(len);
9019 if (buf == NULL)
9020 return PyErr_NoMemory();
9021 confstr(name, buf, len);
9022 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9023 PyMem_Free(buf);
9024 }
9025 else
9026 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009027 return result;
9028}
9029#endif
9030
9031
9032#ifdef HAVE_SYSCONF
9033static struct constdef posix_constants_sysconf[] = {
9034#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009035 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009036#endif
9037#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009038 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009039#endif
9040#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009041 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009042#endif
9043#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009044 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009045#endif
9046#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009047 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009048#endif
9049#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009050 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009051#endif
9052#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009053 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009054#endif
9055#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009056 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009057#endif
9058#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009059 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009060#endif
9061#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009062 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009063#endif
Fred Draked86ed291999-12-15 15:34:33 +00009064#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009065 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009066#endif
9067#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009068 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009069#endif
Fred Drakec9680921999-12-13 16:37:25 +00009070#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009071 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009072#endif
Fred Drakec9680921999-12-13 16:37:25 +00009073#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009074 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009075#endif
9076#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009077 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009078#endif
9079#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009080 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009081#endif
9082#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009083 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009084#endif
9085#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009086 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009087#endif
Fred Draked86ed291999-12-15 15:34:33 +00009088#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009089 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009090#endif
Fred Drakec9680921999-12-13 16:37:25 +00009091#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009092 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009093#endif
9094#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009095 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009096#endif
9097#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009098 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009099#endif
9100#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009101 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009102#endif
9103#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009104 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009105#endif
Fred Draked86ed291999-12-15 15:34:33 +00009106#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009107 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009108#endif
Fred Drakec9680921999-12-13 16:37:25 +00009109#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009110 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009111#endif
9112#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009113 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009114#endif
9115#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009116 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009117#endif
9118#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009119 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009120#endif
9121#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009122 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009123#endif
9124#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009125 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009126#endif
9127#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009128 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009129#endif
9130#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009131 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009132#endif
9133#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009134 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009135#endif
9136#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009137 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009138#endif
9139#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009140 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009141#endif
9142#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009143 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009144#endif
9145#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009146 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009147#endif
9148#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009149 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009150#endif
9151#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009152 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009153#endif
9154#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009155 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009156#endif
9157#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009158 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009159#endif
9160#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009161 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009162#endif
9163#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009164 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009165#endif
9166#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009167 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009168#endif
9169#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009170 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009171#endif
9172#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009173 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009174#endif
9175#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009176 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009177#endif
Fred Draked86ed291999-12-15 15:34:33 +00009178#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009179 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009180#endif
Fred Drakec9680921999-12-13 16:37:25 +00009181#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009182 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009183#endif
9184#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009185 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009186#endif
9187#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009188 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009189#endif
Fred Draked86ed291999-12-15 15:34:33 +00009190#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009191 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009192#endif
Fred Drakec9680921999-12-13 16:37:25 +00009193#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009194 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009195#endif
Fred Draked86ed291999-12-15 15:34:33 +00009196#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009197 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009198#endif
9199#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009200 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009201#endif
Fred Drakec9680921999-12-13 16:37:25 +00009202#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009203 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009204#endif
9205#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009206 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009207#endif
9208#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009209 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009210#endif
9211#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009212 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009213#endif
Fred Draked86ed291999-12-15 15:34:33 +00009214#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009215 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009216#endif
Fred Drakec9680921999-12-13 16:37:25 +00009217#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009218 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009219#endif
9220#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009221 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009222#endif
9223#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009224 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009225#endif
9226#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009227 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009228#endif
9229#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009230 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009231#endif
9232#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009233 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009234#endif
9235#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009236 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009237#endif
Fred Draked86ed291999-12-15 15:34:33 +00009238#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009239 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009240#endif
Fred Drakec9680921999-12-13 16:37:25 +00009241#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009242 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009243#endif
9244#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009245 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009246#endif
Fred Draked86ed291999-12-15 15:34:33 +00009247#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009248 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009249#endif
Fred Drakec9680921999-12-13 16:37:25 +00009250#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009251 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009252#endif
9253#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009254 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009255#endif
9256#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009257 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009258#endif
9259#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009260 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009261#endif
9262#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009263 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009264#endif
9265#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009266 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009267#endif
9268#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009269 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009270#endif
9271#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009272 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009273#endif
9274#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009275 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009276#endif
Fred Draked86ed291999-12-15 15:34:33 +00009277#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009278 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009279#endif
9280#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009281 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009282#endif
Fred Drakec9680921999-12-13 16:37:25 +00009283#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009284 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009285#endif
9286#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009287 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009288#endif
9289#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009290 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009291#endif
9292#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009293 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009294#endif
9295#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009296 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009297#endif
9298#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009299 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009300#endif
9301#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009302 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009303#endif
9304#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009305 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009306#endif
9307#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009308 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009309#endif
9310#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009311 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009312#endif
9313#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00009314 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00009315#endif
9316#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009317 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00009318#endif
9319#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009320 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00009321#endif
9322#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00009323 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00009324#endif
9325#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00009326 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00009327#endif
9328#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00009329 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00009330#endif
9331#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00009332 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00009333#endif
9334#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009335 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009336#endif
9337#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009338 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009339#endif
9340#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00009341 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00009342#endif
9343#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009344 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009345#endif
9346#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009347 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009348#endif
9349#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00009350 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00009351#endif
9352#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009353 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009354#endif
9355#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009356 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009357#endif
9358#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009359 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00009360#endif
9361#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00009362 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00009363#endif
9364#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009365 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009366#endif
9367#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009368 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009369#endif
9370#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009371 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00009372#endif
9373#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009374 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009375#endif
9376#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009377 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009378#endif
9379#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009380 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009381#endif
9382#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009383 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009384#endif
9385#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009386 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009387#endif
Fred Draked86ed291999-12-15 15:34:33 +00009388#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00009389 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00009390#endif
Fred Drakec9680921999-12-13 16:37:25 +00009391#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00009392 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00009393#endif
9394#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009395 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009396#endif
9397#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00009398 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00009399#endif
9400#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009401 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009402#endif
9403#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009404 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009405#endif
9406#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009407 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009408#endif
9409#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00009410 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00009411#endif
9412#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009413 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009414#endif
9415#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009416 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009417#endif
9418#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009419 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009420#endif
9421#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009422 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009423#endif
9424#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009425 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00009426#endif
9427#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009428 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00009429#endif
9430#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00009431 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00009432#endif
9433#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009434 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009435#endif
9436#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009437 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009438#endif
9439#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009440 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009441#endif
9442#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009443 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00009444#endif
9445#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009446 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009447#endif
9448#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009449 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009450#endif
9451#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009452 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009453#endif
9454#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009455 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009456#endif
9457#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009458 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009459#endif
9460#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009461 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009462#endif
9463#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00009464 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00009465#endif
9466#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009467 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009468#endif
9469#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009470 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009471#endif
9472#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009473 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009474#endif
9475#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009476 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009477#endif
9478#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00009479 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00009480#endif
9481#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009482 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009483#endif
9484#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00009485 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00009486#endif
9487#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009488 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009489#endif
9490#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00009491 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00009492#endif
9493#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00009494 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00009495#endif
9496#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00009497 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00009498#endif
9499#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00009500 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00009501#endif
9502#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009503 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009504#endif
9505#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00009506 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00009507#endif
9508#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00009509 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00009510#endif
9511#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009512 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009513#endif
9514#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009515 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009516#endif
9517#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00009518 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00009519#endif
9520#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00009521 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00009522#endif
9523#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00009524 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00009525#endif
9526};
9527
9528static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009529conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009530{
9531 return conv_confname(arg, valuep, posix_constants_sysconf,
9532 sizeof(posix_constants_sysconf)
9533 / sizeof(struct constdef));
9534}
9535
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009536PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009537"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009538Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009539
9540static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009541posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009542{
9543 PyObject *result = NULL;
9544 int name;
9545
9546 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
9547 int value;
9548
9549 errno = 0;
9550 value = sysconf(name);
9551 if (value == -1 && errno != 0)
9552 posix_error();
9553 else
Christian Heimes217cfd12007-12-02 14:31:20 +00009554 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00009555 }
9556 return result;
9557}
9558#endif
9559
9560
Fred Drakebec628d1999-12-15 18:31:10 +00009561/* This code is used to ensure that the tables of configuration value names
9562 * are in sorted order as required by conv_confname(), and also to build the
9563 * the exported dictionaries that are used to publish information about the
9564 * names available on the host platform.
9565 *
9566 * Sorting the table at runtime ensures that the table is properly ordered
9567 * when used, even for platforms we're not able to test on. It also makes
9568 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00009569 */
Fred Drakebec628d1999-12-15 18:31:10 +00009570
9571static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009572cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00009573{
9574 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009575 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00009576 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009577 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00009578
9579 return strcmp(c1->name, c2->name);
9580}
9581
9582static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009583setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00009584 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009585{
Fred Drakebec628d1999-12-15 18:31:10 +00009586 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00009587 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00009588
9589 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
9590 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00009591 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00009592 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009593
Barry Warsaw3155db32000-04-13 15:20:40 +00009594 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009595 PyObject *o = PyLong_FromLong(table[i].value);
9596 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
9597 Py_XDECREF(o);
9598 Py_DECREF(d);
9599 return -1;
9600 }
9601 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00009602 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00009603 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00009604}
9605
Fred Drakebec628d1999-12-15 18:31:10 +00009606/* Return -1 on failure, 0 on success. */
9607static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00009608setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009609{
9610#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00009611 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00009612 sizeof(posix_constants_pathconf)
9613 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009614 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009615 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009616#endif
9617#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00009618 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00009619 sizeof(posix_constants_confstr)
9620 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009621 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009622 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009623#endif
9624#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00009625 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00009626 sizeof(posix_constants_sysconf)
9627 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009628 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009629 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009630#endif
Fred Drakebec628d1999-12-15 18:31:10 +00009631 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00009632}
Fred Draked86ed291999-12-15 15:34:33 +00009633
9634
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009635PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009636"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009637Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009638in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009639
9640static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009641posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009642{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009643 abort();
9644 /*NOTREACHED*/
9645 Py_FatalError("abort() called from Python code didn't abort!");
9646 return NULL;
9647}
Fred Drakebec628d1999-12-15 18:31:10 +00009648
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00009649#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009650PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00009651"startfile(filepath [, operation]) - Start a file with its associated\n\
9652application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009653\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00009654When \"operation\" is not specified or \"open\", this acts like\n\
9655double-clicking the file in Explorer, or giving the file name as an\n\
9656argument to the DOS \"start\" command: the file is opened with whatever\n\
9657application (if any) its extension is associated.\n\
9658When another \"operation\" is given, it specifies what should be done with\n\
9659the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009660\n\
9661startfile returns as soon as the associated application is launched.\n\
9662There is no option to wait for the application to close, and no way\n\
9663to retrieve the application's exit status.\n\
9664\n\
9665The filepath is relative to the current directory. If you want to use\n\
9666an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009667the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00009668
9669static PyObject *
9670win32_startfile(PyObject *self, PyObject *args)
9671{
Victor Stinner8c62be82010-05-06 00:08:46 +00009672 PyObject *ofilepath;
9673 char *filepath;
9674 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02009675 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +00009676 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00009677
Victor Stinnereb5657a2011-09-30 01:44:27 +02009678 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009679 if (!PyArg_ParseTuple(args, "U|s:startfile",
9680 &unipath, &operation)) {
9681 PyErr_Clear();
9682 goto normal;
9683 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009684
Victor Stinner8c62be82010-05-06 00:08:46 +00009685 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009686 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +00009687 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +02009688 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009689 PyErr_Clear();
9690 operation = NULL;
9691 goto normal;
9692 }
9693 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009694
Victor Stinnereb5657a2011-09-30 01:44:27 +02009695 wpath = PyUnicode_AsUnicode(unipath);
9696 if (wpath == NULL)
9697 goto normal;
9698 if (uoperation) {
9699 woperation = PyUnicode_AsUnicode(uoperation);
9700 if (woperation == NULL)
9701 goto normal;
9702 }
9703 else
9704 woperation = NULL;
9705
Victor Stinner8c62be82010-05-06 00:08:46 +00009706 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02009707 rc = ShellExecuteW((HWND)0, woperation, wpath,
9708 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +00009709 Py_END_ALLOW_THREADS
9710
Victor Stinnereb5657a2011-09-30 01:44:27 +02009711 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +00009712 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009713 win32_error_object("startfile", unipath);
9714 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009715 }
9716 Py_INCREF(Py_None);
9717 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009718
9719normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00009720 if (!PyArg_ParseTuple(args, "O&|s:startfile",
9721 PyUnicode_FSConverter, &ofilepath,
9722 &operation))
9723 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01009724 if (win32_warn_bytes_api()) {
9725 Py_DECREF(ofilepath);
9726 return NULL;
9727 }
Victor Stinner8c62be82010-05-06 00:08:46 +00009728 filepath = PyBytes_AsString(ofilepath);
9729 Py_BEGIN_ALLOW_THREADS
9730 rc = ShellExecute((HWND)0, operation, filepath,
9731 NULL, NULL, SW_SHOWNORMAL);
9732 Py_END_ALLOW_THREADS
9733 if (rc <= (HINSTANCE)32) {
9734 PyObject *errval = win32_error("startfile", filepath);
9735 Py_DECREF(ofilepath);
9736 return errval;
9737 }
9738 Py_DECREF(ofilepath);
9739 Py_INCREF(Py_None);
9740 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00009741}
9742#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009743
Martin v. Löwis438b5342002-12-27 10:16:42 +00009744#ifdef HAVE_GETLOADAVG
9745PyDoc_STRVAR(posix_getloadavg__doc__,
9746"getloadavg() -> (float, float, float)\n\n\
9747Return the number of processes in the system run queue averaged over\n\
9748the last 1, 5, and 15 minutes or raises OSError if the load average\n\
9749was unobtainable");
9750
9751static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009752posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00009753{
9754 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00009755 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009756 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
9757 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00009758 } else
Stefan Krah0e803b32010-11-26 16:16:47 +00009759 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00009760}
9761#endif
9762
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009763PyDoc_STRVAR(device_encoding__doc__,
9764"device_encoding(fd) -> str\n\n\
9765Return a string describing the encoding of the device\n\
9766if the output is a terminal; else return None.");
9767
9768static PyObject *
9769device_encoding(PyObject *self, PyObject *args)
9770{
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -05009772
Victor Stinner8c62be82010-05-06 00:08:46 +00009773 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
9774 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -05009775
9776 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009777}
9778
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009779#ifdef HAVE_SETRESUID
9780PyDoc_STRVAR(posix_setresuid__doc__,
9781"setresuid(ruid, euid, suid)\n\n\
9782Set the current process's real, effective, and saved user ids.");
9783
9784static PyObject*
9785posix_setresuid (PyObject *self, PyObject *args)
9786{
Victor Stinner8c62be82010-05-06 00:08:46 +00009787 /* We assume uid_t is no larger than a long. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02009788 uid_t ruid, euid, suid;
9789 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
9790 _Py_Uid_Converter, &ruid,
9791 _Py_Uid_Converter, &euid,
9792 _Py_Uid_Converter, &suid))
Victor Stinner8c62be82010-05-06 00:08:46 +00009793 return NULL;
9794 if (setresuid(ruid, euid, suid) < 0)
9795 return posix_error();
9796 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009797}
9798#endif
9799
9800#ifdef HAVE_SETRESGID
9801PyDoc_STRVAR(posix_setresgid__doc__,
9802"setresgid(rgid, egid, sgid)\n\n\
9803Set the current process's real, effective, and saved group ids.");
9804
9805static PyObject*
9806posix_setresgid (PyObject *self, PyObject *args)
9807{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02009808 gid_t rgid, egid, sgid;
9809 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
9810 _Py_Gid_Converter, &rgid,
9811 _Py_Gid_Converter, &egid,
9812 _Py_Gid_Converter, &sgid))
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 return NULL;
9814 if (setresgid(rgid, egid, sgid) < 0)
9815 return posix_error();
9816 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009817}
9818#endif
9819
9820#ifdef HAVE_GETRESUID
9821PyDoc_STRVAR(posix_getresuid__doc__,
9822"getresuid() -> (ruid, euid, suid)\n\n\
9823Get tuple of the current process's real, effective, and saved user ids.");
9824
9825static PyObject*
9826posix_getresuid (PyObject *self, PyObject *noargs)
9827{
Victor Stinner8c62be82010-05-06 00:08:46 +00009828 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +00009829 if (getresuid(&ruid, &euid, &suid) < 0)
9830 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02009831 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
9832 _PyLong_FromUid(euid),
9833 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009834}
9835#endif
9836
9837#ifdef HAVE_GETRESGID
9838PyDoc_STRVAR(posix_getresgid__doc__,
9839"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00009840Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009841
9842static PyObject*
9843posix_getresgid (PyObject *self, PyObject *noargs)
9844{
Victor Stinner8c62be82010-05-06 00:08:46 +00009845 uid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +00009846 if (getresgid(&rgid, &egid, &sgid) < 0)
9847 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02009848 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
9849 _PyLong_FromGid(egid),
9850 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009851}
9852#endif
9853
Benjamin Peterson9428d532011-09-14 11:45:52 -04009854#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -04009855
Benjamin Peterson799bd802011-08-31 22:15:17 -04009856PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009857"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
9858Return the value of extended attribute attribute on path.\n\
9859\n\
9860path may be either a string or an open file descriptor.\n\
9861If follow_symlinks is False, and the last element of the path is a symbolic\n\
9862 link, getxattr will examine the symbolic link itself instead of the file\n\
9863 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -04009864
9865static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009866posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04009867{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009868 path_t path;
9869 path_t attribute;
9870 int follow_symlinks = 1;
9871 PyObject *buffer = NULL;
9872 int i;
9873 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -04009874
Larry Hastings9cf065c2012-06-22 16:30:09 -07009875 memset(&path, 0, sizeof(path));
9876 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +01009877 path.function_name = "getxattr";
9878 attribute.function_name = "getxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009879 path.allow_fd = 1;
9880 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
9881 path_converter, &path,
9882 path_converter, &attribute,
9883 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -04009884 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009885
Larry Hastings9cf065c2012-06-22 16:30:09 -07009886 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
9887 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009888
Larry Hastings9cf065c2012-06-22 16:30:09 -07009889 for (i = 0; ; i++) {
9890 void *ptr;
9891 ssize_t result;
9892 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
9893 Py_ssize_t buffer_size = buffer_sizes[i];
9894 if (!buffer_size) {
Victor Stinner292c8352012-10-30 02:17:38 +01009895 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009896 goto exit;
9897 }
9898 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
9899 if (!buffer)
9900 goto exit;
9901 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009902
Larry Hastings9cf065c2012-06-22 16:30:09 -07009903 Py_BEGIN_ALLOW_THREADS;
9904 if (path.fd >= 0)
9905 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
9906 else if (follow_symlinks)
9907 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
9908 else
9909 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
9910 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009911
Larry Hastings9cf065c2012-06-22 16:30:09 -07009912 if (result < 0) {
9913 Py_DECREF(buffer);
9914 buffer = NULL;
9915 if (errno == ERANGE)
9916 continue;
Victor Stinner292c8352012-10-30 02:17:38 +01009917 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009918 goto exit;
9919 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009920
Larry Hastings9cf065c2012-06-22 16:30:09 -07009921 if (result != buffer_size) {
9922 /* Can only shrink. */
9923 _PyBytes_Resize(&buffer, result);
9924 }
9925 break;
9926 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009927
Larry Hastings9cf065c2012-06-22 16:30:09 -07009928exit:
9929 path_cleanup(&path);
9930 path_cleanup(&attribute);
9931 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009932}
9933
9934PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009935"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
9936Set extended attribute attribute on path to value.\n\
9937path may be either a string or an open file descriptor.\n\
9938If follow_symlinks is False, and the last element of the path is a symbolic\n\
9939 link, setxattr will modify the symbolic link itself instead of the file\n\
9940 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -04009941
9942static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009943posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04009944{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009945 path_t path;
9946 path_t attribute;
9947 Py_buffer value;
9948 int flags = 0;
9949 int follow_symlinks = 1;
9950 int result;
9951 PyObject *return_value = NULL;
9952 static char *keywords[] = {"path", "attribute", "value",
9953 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -04009954
Larry Hastings9cf065c2012-06-22 16:30:09 -07009955 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009956 path.function_name = "setxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009957 path.allow_fd = 1;
9958 memset(&attribute, 0, sizeof(attribute));
9959 memset(&value, 0, sizeof(value));
9960 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
9961 keywords,
9962 path_converter, &path,
9963 path_converter, &attribute,
9964 &value, &flags,
9965 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -04009966 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009967
9968 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
9969 goto exit;
9970
Benjamin Peterson799bd802011-08-31 22:15:17 -04009971 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009972 if (path.fd > -1)
9973 result = fsetxattr(path.fd, attribute.narrow,
9974 value.buf, value.len, flags);
9975 else if (follow_symlinks)
9976 result = setxattr(path.narrow, attribute.narrow,
9977 value.buf, value.len, flags);
9978 else
9979 result = lsetxattr(path.narrow, attribute.narrow,
9980 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009981 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009982
Larry Hastings9cf065c2012-06-22 16:30:09 -07009983 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01009984 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009985 goto exit;
9986 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009987
Larry Hastings9cf065c2012-06-22 16:30:09 -07009988 return_value = Py_None;
9989 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009990
Larry Hastings9cf065c2012-06-22 16:30:09 -07009991exit:
9992 path_cleanup(&path);
9993 path_cleanup(&attribute);
9994 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009995
Larry Hastings9cf065c2012-06-22 16:30:09 -07009996 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009997}
9998
9999PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010000"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10001Remove extended attribute attribute on path.\n\
10002path may be either a string or an open file descriptor.\n\
10003If follow_symlinks is False, and the last element of the path is a symbolic\n\
10004 link, removexattr will modify the symbolic link itself instead of the file\n\
10005 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010006
10007static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010008posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010009{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010010 path_t path;
10011 path_t attribute;
10012 int follow_symlinks = 1;
10013 int result;
10014 PyObject *return_value = NULL;
10015 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010016
Larry Hastings9cf065c2012-06-22 16:30:09 -070010017 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010018 path.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010019 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010020 attribute.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010021 path.allow_fd = 1;
10022 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10023 keywords,
10024 path_converter, &path,
10025 path_converter, &attribute,
10026 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010027 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010028
10029 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10030 goto exit;
10031
Benjamin Peterson799bd802011-08-31 22:15:17 -040010032 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010033 if (path.fd > -1)
10034 result = fremovexattr(path.fd, attribute.narrow);
10035 else if (follow_symlinks)
10036 result = removexattr(path.narrow, attribute.narrow);
10037 else
10038 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010039 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010040
Larry Hastings9cf065c2012-06-22 16:30:09 -070010041 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010042 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010043 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010044 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010045
Larry Hastings9cf065c2012-06-22 16:30:09 -070010046 return_value = Py_None;
10047 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010048
Larry Hastings9cf065c2012-06-22 16:30:09 -070010049exit:
10050 path_cleanup(&path);
10051 path_cleanup(&attribute);
10052
10053 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010054}
10055
10056PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010057"listxattr(path='.', *, follow_symlinks=True)\n\n\
10058Return a list of extended attributes on path.\n\
10059\n\
10060path may be either None, a string, or an open file descriptor.\n\
10061if path is None, listxattr will examine the current directory.\n\
10062If follow_symlinks is False, and the last element of the path is a symbolic\n\
10063 link, listxattr will examine the symbolic link itself instead of the file\n\
10064 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010065
10066static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010067posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010068{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010069 path_t path;
10070 int follow_symlinks = 1;
10071 Py_ssize_t i;
10072 PyObject *result = NULL;
10073 char *buffer = NULL;
10074 char *name;
10075 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010076
Larry Hastings9cf065c2012-06-22 16:30:09 -070010077 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010078 path.function_name = "listxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010079 path.allow_fd = 1;
10080 path.fd = -1;
10081 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10082 path_converter, &path,
10083 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010084 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010085
Larry Hastings9cf065c2012-06-22 16:30:09 -070010086 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10087 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010088
Larry Hastings9cf065c2012-06-22 16:30:09 -070010089 name = path.narrow ? path.narrow : ".";
10090 for (i = 0; ; i++) {
10091 char *start, *trace, *end;
10092 ssize_t length;
10093 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10094 Py_ssize_t buffer_size = buffer_sizes[i];
10095 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010096 /* ERANGE */
Victor Stinner292c8352012-10-30 02:17:38 +010010097 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010098 break;
10099 }
10100 buffer = PyMem_MALLOC(buffer_size);
10101 if (!buffer) {
10102 PyErr_NoMemory();
10103 break;
10104 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010105
Larry Hastings9cf065c2012-06-22 16:30:09 -070010106 Py_BEGIN_ALLOW_THREADS;
10107 if (path.fd > -1)
10108 length = flistxattr(path.fd, buffer, buffer_size);
10109 else if (follow_symlinks)
10110 length = listxattr(name, buffer, buffer_size);
10111 else
10112 length = llistxattr(name, buffer, buffer_size);
10113 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010114
Larry Hastings9cf065c2012-06-22 16:30:09 -070010115 if (length < 0) {
10116 if (errno == ERANGE)
10117 continue;
Victor Stinner292c8352012-10-30 02:17:38 +010010118 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010119 break;
10120 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010121
Larry Hastings9cf065c2012-06-22 16:30:09 -070010122 result = PyList_New(0);
10123 if (!result) {
10124 goto exit;
10125 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010126
Larry Hastings9cf065c2012-06-22 16:30:09 -070010127 end = buffer + length;
10128 for (trace = start = buffer; trace != end; trace++) {
10129 if (!*trace) {
10130 int error;
10131 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10132 trace - start);
10133 if (!attribute) {
10134 Py_DECREF(result);
10135 result = NULL;
10136 goto exit;
10137 }
10138 error = PyList_Append(result, attribute);
10139 Py_DECREF(attribute);
10140 if (error) {
10141 Py_DECREF(result);
10142 result = NULL;
10143 goto exit;
10144 }
10145 start = trace + 1;
10146 }
10147 }
10148 break;
10149 }
10150exit:
10151 path_cleanup(&path);
10152 if (buffer)
10153 PyMem_FREE(buffer);
10154 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010155}
10156
Benjamin Peterson9428d532011-09-14 11:45:52 -040010157#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010158
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010159
Georg Brandl2fb477c2012-02-21 00:33:36 +010010160PyDoc_STRVAR(posix_urandom__doc__,
10161"urandom(n) -> str\n\n\
10162Return n random bytes suitable for cryptographic use.");
10163
10164static PyObject *
10165posix_urandom(PyObject *self, PyObject *args)
10166{
10167 Py_ssize_t size;
10168 PyObject *result;
10169 int ret;
10170
10171 /* Read arguments */
10172 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10173 return NULL;
10174 if (size < 0)
10175 return PyErr_Format(PyExc_ValueError,
10176 "negative argument not allowed");
10177 result = PyBytes_FromStringAndSize(NULL, size);
10178 if (result == NULL)
10179 return NULL;
10180
10181 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10182 PyBytes_GET_SIZE(result));
10183 if (ret == -1) {
10184 Py_DECREF(result);
10185 return NULL;
10186 }
10187 return result;
10188}
10189
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010190/* Terminal size querying */
10191
10192static PyTypeObject TerminalSizeType;
10193
10194PyDoc_STRVAR(TerminalSize_docstring,
10195 "A tuple of (columns, lines) for holding terminal window size");
10196
10197static PyStructSequence_Field TerminalSize_fields[] = {
10198 {"columns", "width of the terminal window in characters"},
10199 {"lines", "height of the terminal window in characters"},
10200 {NULL, NULL}
10201};
10202
10203static PyStructSequence_Desc TerminalSize_desc = {
10204 "os.terminal_size",
10205 TerminalSize_docstring,
10206 TerminalSize_fields,
10207 2,
10208};
10209
10210#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10211PyDoc_STRVAR(termsize__doc__,
10212 "Return the size of the terminal window as (columns, lines).\n" \
10213 "\n" \
10214 "The optional argument fd (default standard output) specifies\n" \
10215 "which file descriptor should be queried.\n" \
10216 "\n" \
10217 "If the file descriptor is not connected to a terminal, an OSError\n" \
10218 "is thrown.\n" \
10219 "\n" \
10220 "This function will only be defined if an implementation is\n" \
10221 "available for this system.\n" \
10222 "\n" \
10223 "shutil.get_terminal_size is the high-level function which should \n" \
10224 "normally be used, os.get_terminal_size is the low-level implementation.");
10225
10226static PyObject*
10227get_terminal_size(PyObject *self, PyObject *args)
10228{
10229 int columns, lines;
10230 PyObject *termsize;
10231
10232 int fd = fileno(stdout);
10233 /* Under some conditions stdout may not be connected and
10234 * fileno(stdout) may point to an invalid file descriptor. For example
10235 * GUI apps don't have valid standard streams by default.
10236 *
10237 * If this happens, and the optional fd argument is not present,
10238 * the ioctl below will fail returning EBADF. This is what we want.
10239 */
10240
10241 if (!PyArg_ParseTuple(args, "|i", &fd))
10242 return NULL;
10243
10244#ifdef TERMSIZE_USE_IOCTL
10245 {
10246 struct winsize w;
10247 if (ioctl(fd, TIOCGWINSZ, &w))
10248 return PyErr_SetFromErrno(PyExc_OSError);
10249 columns = w.ws_col;
10250 lines = w.ws_row;
10251 }
10252#endif /* TERMSIZE_USE_IOCTL */
10253
10254#ifdef TERMSIZE_USE_CONIO
10255 {
10256 DWORD nhandle;
10257 HANDLE handle;
10258 CONSOLE_SCREEN_BUFFER_INFO csbi;
10259 switch (fd) {
10260 case 0: nhandle = STD_INPUT_HANDLE;
10261 break;
10262 case 1: nhandle = STD_OUTPUT_HANDLE;
10263 break;
10264 case 2: nhandle = STD_ERROR_HANDLE;
10265 break;
10266 default:
10267 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10268 }
10269 handle = GetStdHandle(nhandle);
10270 if (handle == NULL)
10271 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10272 if (handle == INVALID_HANDLE_VALUE)
10273 return PyErr_SetFromWindowsErr(0);
10274
10275 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10276 return PyErr_SetFromWindowsErr(0);
10277
10278 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10279 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10280 }
10281#endif /* TERMSIZE_USE_CONIO */
10282
10283 termsize = PyStructSequence_New(&TerminalSizeType);
10284 if (termsize == NULL)
10285 return NULL;
10286 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10287 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10288 if (PyErr_Occurred()) {
10289 Py_DECREF(termsize);
10290 return NULL;
10291 }
10292 return termsize;
10293}
10294#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10295
10296
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010297static PyMethodDef posix_methods[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010298 {"access", (PyCFunction)posix_access,
10299 METH_VARARGS | METH_KEYWORDS,
10300 posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010301#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010302 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010303#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010304 {"chdir", (PyCFunction)posix_chdir,
10305 METH_VARARGS | METH_KEYWORDS,
10306 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010307#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010308 {"chflags", (PyCFunction)posix_chflags,
10309 METH_VARARGS | METH_KEYWORDS,
10310 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010311#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010312 {"chmod", (PyCFunction)posix_chmod,
10313 METH_VARARGS | METH_KEYWORDS,
10314 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010315#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010316 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010317#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010318#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070010319 {"chown", (PyCFunction)posix_chown,
10320 METH_VARARGS | METH_KEYWORDS,
10321 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010322#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010323#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010324 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010325#endif /* HAVE_LCHMOD */
10326#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010327 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010328#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010329#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010330 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010331#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010332#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010333 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010334#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010335#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010336 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010337#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010338#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010339 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010340#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010341#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010342 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10343 METH_NOARGS, posix_getcwd__doc__},
10344 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10345 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010346#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010347#if defined(HAVE_LINK) || defined(MS_WINDOWS)
10348 {"link", (PyCFunction)posix_link,
10349 METH_VARARGS | METH_KEYWORDS,
10350 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010351#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010352 {"listdir", (PyCFunction)posix_listdir,
10353 METH_VARARGS | METH_KEYWORDS,
10354 posix_listdir__doc__},
10355 {"lstat", (PyCFunction)posix_lstat,
10356 METH_VARARGS | METH_KEYWORDS,
10357 posix_lstat__doc__},
10358 {"mkdir", (PyCFunction)posix_mkdir,
10359 METH_VARARGS | METH_KEYWORDS,
10360 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010361#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010362 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000010363#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010364#ifdef HAVE_GETPRIORITY
10365 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10366#endif /* HAVE_GETPRIORITY */
10367#ifdef HAVE_SETPRIORITY
10368 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10369#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010370#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070010371 {"readlink", (PyCFunction)posix_readlink,
10372 METH_VARARGS | METH_KEYWORDS,
10373 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010374#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010375#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010376 {"readlink", (PyCFunction)win_readlink,
10377 METH_VARARGS | METH_KEYWORDS,
10378 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010379#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010380 {"rename", (PyCFunction)posix_rename,
10381 METH_VARARGS | METH_KEYWORDS,
10382 posix_rename__doc__},
10383 {"replace", (PyCFunction)posix_replace,
10384 METH_VARARGS | METH_KEYWORDS,
10385 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070010386 {"rmdir", (PyCFunction)posix_rmdir,
10387 METH_VARARGS | METH_KEYWORDS,
10388 posix_rmdir__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010389 {"stat", (PyCFunction)posix_stat,
10390 METH_VARARGS | METH_KEYWORDS,
10391 posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010392 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010393#if defined(HAVE_SYMLINK)
10394 {"symlink", (PyCFunction)posix_symlink,
10395 METH_VARARGS | METH_KEYWORDS,
10396 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010397#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000010398#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010399 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010400#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010401 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010402#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010403 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010404#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010405 {"unlink", (PyCFunction)posix_unlink,
10406 METH_VARARGS | METH_KEYWORDS,
10407 posix_unlink__doc__},
10408 {"remove", (PyCFunction)posix_unlink,
10409 METH_VARARGS | METH_KEYWORDS,
10410 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070010411 {"utime", (PyCFunction)posix_utime,
10412 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000010413#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010414 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010415#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010416 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010417#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010418 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010419 {"execve", (PyCFunction)posix_execve,
10420 METH_VARARGS | METH_KEYWORDS,
10421 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010422#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000010423#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010424 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10425 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +000010426#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010427#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010428 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010429#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010430#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010431 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010432#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010433#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010434#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010435 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
10436 {"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 +020010437#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010438#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010439 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010440#endif
10441#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010442 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010443#endif
10444#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010445 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010446#endif
10447#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010448 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010449#endif
10450#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010451 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010452#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010453 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050010454#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010455 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
10456 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
10457#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010458#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010459#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000010460 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010461#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000010462#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010463 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000010464#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000010465#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010466 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000010467#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010468#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010469 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000010470#endif /* HAVE_GETEUID */
10471#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010472 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010473#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020010474#ifdef HAVE_GETGROUPLIST
10475 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
10476#endif
Fred Drakec9680921999-12-13 16:37:25 +000010477#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010478 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010479#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010480 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010481#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010482 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010483#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010484#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010485 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010486#endif /* HAVE_GETPPID */
10487#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010488 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010489#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000010490#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010491 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000010492#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000010493#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000010494 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010495#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010496#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000010497 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010498#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000010499#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010500 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000010501#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000010502#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010503 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
10504 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000010505#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010506#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010507 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010508#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010509#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010510 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010511#endif /* HAVE_SETEUID */
10512#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010513 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010514#endif /* HAVE_SETEGID */
10515#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010516 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010517#endif /* HAVE_SETREUID */
10518#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010519 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010520#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010521#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010522 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010523#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010524#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010525 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010526#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000010527#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010528 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000010529#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000010530#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010531 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000010532#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010533#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010534 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010535#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010536#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010537 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010538#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010539#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010010540 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010541#endif /* HAVE_WAIT3 */
10542#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010010543 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010544#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010545#if defined(HAVE_WAITID) && !defined(__APPLE__)
10546 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
10547#endif
Tim Petersab034fa2002-02-01 11:27:43 +000010548#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010549 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010550#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010551#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010552 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010553#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010554#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010555 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010556#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010557#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010558 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010559#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010560#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010561 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010562#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010563#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010564 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010565#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010566 {"open", (PyCFunction)posix_open,\
10567 METH_VARARGS | METH_KEYWORDS,
10568 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010569 {"close", posix_close, METH_VARARGS, posix_close__doc__},
10570 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
10571 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
10572 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
10573 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010574#ifdef HAVE_LOCKF
10575 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
10576#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010577 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
10578 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010579#ifdef HAVE_READV
10580 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
10581#endif
10582#ifdef HAVE_PREAD
10583 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
10584#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010585 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010586#ifdef HAVE_WRITEV
10587 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
10588#endif
10589#ifdef HAVE_PWRITE
10590 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
10591#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000010592#ifdef HAVE_SENDFILE
10593 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
10594 posix_sendfile__doc__},
10595#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010010596 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010597 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010598#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010599 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010600#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010601#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020010602 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010603#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010604#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070010605 {"mkfifo", (PyCFunction)posix_mkfifo,
10606 METH_VARARGS | METH_KEYWORDS,
10607 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010608#endif
Neal Norwitz11690112002-07-30 01:08:28 +000010609#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010610 {"mknod", (PyCFunction)posix_mknod,
10611 METH_VARARGS | METH_KEYWORDS,
10612 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000010613#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010614#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000010615 {"major", posix_major, METH_VARARGS, posix_major__doc__},
10616 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
10617 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010618#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010619#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000010620 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010621#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010622#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020010623 {"truncate", (PyCFunction)posix_truncate,
10624 METH_VARARGS | METH_KEYWORDS,
10625 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010626#endif
10627#ifdef HAVE_POSIX_FALLOCATE
10628 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
10629#endif
10630#ifdef HAVE_POSIX_FADVISE
10631 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
10632#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010633#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010634 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010635#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010636#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010637 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000010638#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010639 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010640#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000010641 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010642#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010643#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010644 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010645#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010646#ifdef HAVE_SYNC
10647 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
10648#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010649#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010650 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010651#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000010652#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010653#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000010654 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000010655#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010656#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000010657 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010658#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000010659#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000010660 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010661#endif /* WIFSTOPPED */
10662#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000010663 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010664#endif /* WIFSIGNALED */
10665#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000010666 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010667#endif /* WIFEXITED */
10668#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000010669 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010670#endif /* WEXITSTATUS */
10671#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010672 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010673#endif /* WTERMSIG */
10674#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010675 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010676#endif /* WSTOPSIG */
10677#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000010678#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000010679 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010680#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000010681#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010682 {"statvfs", (PyCFunction)posix_statvfs,
10683 METH_VARARGS | METH_KEYWORDS,
10684 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010685#endif
Fred Drakec9680921999-12-13 16:37:25 +000010686#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000010687 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010688#endif
10689#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010690 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010691#endif
10692#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010693 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010694#endif
10695#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020010696 {"pathconf", (PyCFunction)posix_pathconf,
10697 METH_VARARGS | METH_KEYWORDS,
10698 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010699#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010700 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010701#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010702 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000010703 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050010704 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010705 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000010706#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000010707#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000010708 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000010709#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010010710 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010711#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010712 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010713#endif
10714#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010715 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010716#endif
10717#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010718 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010719#endif
10720#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010721 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010722#endif
10723
Benjamin Peterson9428d532011-09-14 11:45:52 -040010724#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010725 {"setxattr", (PyCFunction)posix_setxattr,
10726 METH_VARARGS | METH_KEYWORDS,
10727 posix_setxattr__doc__},
10728 {"getxattr", (PyCFunction)posix_getxattr,
10729 METH_VARARGS | METH_KEYWORDS,
10730 posix_getxattr__doc__},
10731 {"removexattr", (PyCFunction)posix_removexattr,
10732 METH_VARARGS | METH_KEYWORDS,
10733 posix_removexattr__doc__},
10734 {"listxattr", (PyCFunction)posix_listxattr,
10735 METH_VARARGS | METH_KEYWORDS,
10736 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040010737#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010738#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10739 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
10740#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010741 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010742};
10743
10744
Barry Warsaw4a342091996-12-19 23:50:02 +000010745static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010746ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000010747{
Victor Stinner8c62be82010-05-06 00:08:46 +000010748 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000010749}
10750
Brian Curtin52173d42010-12-02 18:29:18 +000010751#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000010752static int
Brian Curtin52173d42010-12-02 18:29:18 +000010753enable_symlink()
10754{
10755 HANDLE tok;
10756 TOKEN_PRIVILEGES tok_priv;
10757 LUID luid;
10758 int meth_idx = 0;
10759
10760 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000010761 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000010762
10763 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000010764 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000010765
10766 tok_priv.PrivilegeCount = 1;
10767 tok_priv.Privileges[0].Luid = luid;
10768 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
10769
10770 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
10771 sizeof(TOKEN_PRIVILEGES),
10772 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000010773 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000010774
Brian Curtin3b4499c2010-12-28 14:31:47 +000010775 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
10776 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000010777}
10778#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
10779
Barry Warsaw4a342091996-12-19 23:50:02 +000010780static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000010781all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000010782{
Guido van Rossum94f6f721999-01-06 18:42:14 +000010783#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010784 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010785#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010786#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010787 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010788#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010789#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010790 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010791#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010792#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010793 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010794#endif
Fred Drakec9680921999-12-13 16:37:25 +000010795#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010796 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000010797#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010798#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010799 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010800#endif
Fred Drake106c1a02002-04-23 15:58:02 +000010801#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000010802 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000010803#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000010804#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000010805 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010806#endif
Fred Drake106c1a02002-04-23 15:58:02 +000010807#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000010808 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000010809#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000010810#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000010811 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010812#endif
10813#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000010814 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010815#endif
10816#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000010817 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010818#endif
10819#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000010820 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010821#endif
10822#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010823 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010824#endif
10825#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000010826 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010827#endif
10828#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010829 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010830#endif
10831#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010832 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010833#endif
10834#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010835 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010836#endif
10837#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010838 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010839#endif
10840#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000010841 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010842#endif
10843#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000010844 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010845#endif
10846#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010847 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010848#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000010849#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000010850 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000010851#endif
10852#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000010853 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000010854#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020010855#ifdef O_XATTR
10856 if (ins(d, "O_XATTR", (long)O_XATTR)) return -1;
10857#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010858#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000010859 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010860#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000010861#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010862 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000010863#endif
10864#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010865 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000010866#endif
Jesus Ceacf381202012-04-24 20:44:40 +020010867#ifdef O_EXEC
10868 if (ins(d, "O_EXEC", (long)O_EXEC)) return -1;
10869#endif
10870#ifdef O_SEARCH
10871 if (ins(d, "O_SEARCH", (long)O_SEARCH)) return -1;
10872#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050010873#ifdef O_PATH
10874 if (ins(d, "O_PATH", (long)O_PATH)) return -1;
10875#endif
Jesus Ceacf381202012-04-24 20:44:40 +020010876#ifdef O_TTY_INIT
10877 if (ins(d, "O_TTY_INIT", (long)O_TTY_INIT)) return -1;
10878#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010879#ifdef PRIO_PROCESS
10880 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
10881#endif
10882#ifdef PRIO_PGRP
10883 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
10884#endif
10885#ifdef PRIO_USER
10886 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
10887#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020010888#ifdef O_CLOEXEC
10889 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
10890#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020010891#ifdef O_ACCMODE
10892 if (ins(d, "O_ACCMODE", (long)O_ACCMODE)) return -1;
10893#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010894
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010895
Jesus Cea94363612012-06-22 18:32:07 +020010896#ifdef SEEK_HOLE
10897 if (ins(d, "SEEK_HOLE", (long)SEEK_HOLE)) return -1;
10898#endif
10899#ifdef SEEK_DATA
10900 if (ins(d, "SEEK_DATA", (long)SEEK_DATA)) return -1;
10901#endif
10902
Tim Peters5aa91602002-01-30 05:46:57 +000010903/* MS Windows */
10904#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010905 /* Don't inherit in child processes. */
10906 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010907#endif
10908#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000010909 /* Optimize for short life (keep in memory). */
10910 /* MS forgot to define this one with a non-underscore form too. */
10911 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010912#endif
10913#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000010914 /* Automatically delete when last handle is closed. */
10915 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010916#endif
10917#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000010918 /* Optimize for random access. */
10919 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010920#endif
10921#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010922 /* Optimize for sequential access. */
10923 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010924#endif
10925
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010926/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000010927#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010928 /* Send a SIGIO signal whenever input or output
10929 becomes available on file descriptor */
10930 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000010931#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010932#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010933 /* Direct disk access. */
10934 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010935#endif
10936#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000010937 /* Must be a directory. */
10938 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010939#endif
10940#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000010941 /* Do not follow links. */
10942 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010943#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020010944#ifdef O_NOLINKS
10945 /* Fails if link count of the named file is greater than 1 */
10946 if (ins(d, "O_NOLINKS", (long)O_NOLINKS)) return -1;
10947#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000010948#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010949 /* Do not update the access time. */
10950 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000010951#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000010952
Victor Stinner8c62be82010-05-06 00:08:46 +000010953 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010954#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010955 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010956#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010957#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010958 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010959#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010960#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000010961 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010962#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010963#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010964 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010965#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010966#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000010967 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010968#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010969#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000010970 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010971#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010972#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010973 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010974#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010975#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000010976 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010977#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010978#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000010979 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010980#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010981#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000010982 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010983#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010984#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000010985 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010986#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010987#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000010988 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010989#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010990#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000010991 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010992#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010993#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000010994 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010995#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010996#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010997 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010998#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010999#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011000 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011001#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011002#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000011003 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011004#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011005
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011006 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011007#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011008 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011009#endif /* ST_RDONLY */
11010#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011011 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011012#endif /* ST_NOSUID */
11013
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011014 /* FreeBSD sendfile() constants */
11015#ifdef SF_NODISKIO
11016 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
11017#endif
11018#ifdef SF_MNOWAIT
11019 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
11020#endif
11021#ifdef SF_SYNC
11022 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
11023#endif
11024
Ross Lagerwall7807c352011-03-17 20:20:30 +020011025 /* constants for posix_fadvise */
11026#ifdef POSIX_FADV_NORMAL
11027 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
11028#endif
11029#ifdef POSIX_FADV_SEQUENTIAL
11030 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
11031#endif
11032#ifdef POSIX_FADV_RANDOM
11033 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
11034#endif
11035#ifdef POSIX_FADV_NOREUSE
11036 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
11037#endif
11038#ifdef POSIX_FADV_WILLNEED
11039 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
11040#endif
11041#ifdef POSIX_FADV_DONTNEED
11042 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
11043#endif
11044
11045 /* constants for waitid */
11046#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
11047 if (ins(d, "P_PID", (long)P_PID)) return -1;
11048 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
11049 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
11050#endif
11051#ifdef WEXITED
11052 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
11053#endif
11054#ifdef WNOWAIT
11055 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
11056#endif
11057#ifdef WSTOPPED
11058 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
11059#endif
11060#ifdef CLD_EXITED
11061 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
11062#endif
11063#ifdef CLD_DUMPED
11064 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
11065#endif
11066#ifdef CLD_TRAPPED
11067 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
11068#endif
11069#ifdef CLD_CONTINUED
11070 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
11071#endif
11072
11073 /* constants for lockf */
11074#ifdef F_LOCK
11075 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
11076#endif
11077#ifdef F_TLOCK
11078 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
11079#endif
11080#ifdef F_ULOCK
11081 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
11082#endif
11083#ifdef F_TEST
11084 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
11085#endif
11086
Guido van Rossum246bc171999-02-01 23:54:31 +000011087#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000011088 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
11089 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
11090 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
11091 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
11092 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011093#endif
11094
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011095#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011096 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011097 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11098 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11099#ifdef SCHED_SPORADIC
11100 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
11101#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011102#ifdef SCHED_BATCH
11103 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11104#endif
11105#ifdef SCHED_IDLE
11106 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11107#endif
11108#ifdef SCHED_RESET_ON_FORK
11109 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11110#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011111#ifdef SCHED_SYS
11112 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11113#endif
11114#ifdef SCHED_IA
11115 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11116#endif
11117#ifdef SCHED_FSS
11118 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11119#endif
11120#ifdef SCHED_FX
11121 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11122#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011123#endif
11124
Benjamin Peterson9428d532011-09-14 11:45:52 -040011125#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011126 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11127 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11128 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11129#endif
11130
Victor Stinner8b905bd2011-10-25 13:34:04 +020011131#ifdef RTLD_LAZY
11132 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11133#endif
11134#ifdef RTLD_NOW
11135 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11136#endif
11137#ifdef RTLD_GLOBAL
11138 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11139#endif
11140#ifdef RTLD_LOCAL
11141 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11142#endif
11143#ifdef RTLD_NODELETE
11144 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11145#endif
11146#ifdef RTLD_NOLOAD
11147 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11148#endif
11149#ifdef RTLD_DEEPBIND
11150 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11151#endif
11152
Victor Stinner8c62be82010-05-06 00:08:46 +000011153 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011154}
11155
11156
Tim Peters5aa91602002-01-30 05:46:57 +000011157#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011158#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011159#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011160
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011161#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011162#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011163#define MODNAME "posix"
11164#endif
11165
Martin v. Löwis1a214512008-06-11 05:26:20 +000011166static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011167 PyModuleDef_HEAD_INIT,
11168 MODNAME,
11169 posix__doc__,
11170 -1,
11171 posix_methods,
11172 NULL,
11173 NULL,
11174 NULL,
11175 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011176};
11177
11178
Larry Hastings9cf065c2012-06-22 16:30:09 -070011179static char *have_functions[] = {
11180
11181#ifdef HAVE_FACCESSAT
11182 "HAVE_FACCESSAT",
11183#endif
11184
11185#ifdef HAVE_FCHDIR
11186 "HAVE_FCHDIR",
11187#endif
11188
11189#ifdef HAVE_FCHMOD
11190 "HAVE_FCHMOD",
11191#endif
11192
11193#ifdef HAVE_FCHMODAT
11194 "HAVE_FCHMODAT",
11195#endif
11196
11197#ifdef HAVE_FCHOWN
11198 "HAVE_FCHOWN",
11199#endif
11200
11201#ifdef HAVE_FEXECVE
11202 "HAVE_FEXECVE",
11203#endif
11204
11205#ifdef HAVE_FDOPENDIR
11206 "HAVE_FDOPENDIR",
11207#endif
11208
Georg Brandl306336b2012-06-24 12:55:33 +020011209#ifdef HAVE_FPATHCONF
11210 "HAVE_FPATHCONF",
11211#endif
11212
Larry Hastings9cf065c2012-06-22 16:30:09 -070011213#ifdef HAVE_FSTATAT
11214 "HAVE_FSTATAT",
11215#endif
11216
11217#ifdef HAVE_FSTATVFS
11218 "HAVE_FSTATVFS",
11219#endif
11220
Georg Brandl306336b2012-06-24 12:55:33 +020011221#ifdef HAVE_FTRUNCATE
11222 "HAVE_FTRUNCATE",
11223#endif
11224
Larry Hastings9cf065c2012-06-22 16:30:09 -070011225#ifdef HAVE_FUTIMENS
11226 "HAVE_FUTIMENS",
11227#endif
11228
11229#ifdef HAVE_FUTIMES
11230 "HAVE_FUTIMES",
11231#endif
11232
11233#ifdef HAVE_FUTIMESAT
11234 "HAVE_FUTIMESAT",
11235#endif
11236
11237#ifdef HAVE_LINKAT
11238 "HAVE_LINKAT",
11239#endif
11240
11241#ifdef HAVE_LCHFLAGS
11242 "HAVE_LCHFLAGS",
11243#endif
11244
11245#ifdef HAVE_LCHMOD
11246 "HAVE_LCHMOD",
11247#endif
11248
11249#ifdef HAVE_LCHOWN
11250 "HAVE_LCHOWN",
11251#endif
11252
11253#ifdef HAVE_LSTAT
11254 "HAVE_LSTAT",
11255#endif
11256
11257#ifdef HAVE_LUTIMES
11258 "HAVE_LUTIMES",
11259#endif
11260
11261#ifdef HAVE_MKDIRAT
11262 "HAVE_MKDIRAT",
11263#endif
11264
11265#ifdef HAVE_MKFIFOAT
11266 "HAVE_MKFIFOAT",
11267#endif
11268
11269#ifdef HAVE_MKNODAT
11270 "HAVE_MKNODAT",
11271#endif
11272
11273#ifdef HAVE_OPENAT
11274 "HAVE_OPENAT",
11275#endif
11276
11277#ifdef HAVE_READLINKAT
11278 "HAVE_READLINKAT",
11279#endif
11280
11281#ifdef HAVE_RENAMEAT
11282 "HAVE_RENAMEAT",
11283#endif
11284
11285#ifdef HAVE_SYMLINKAT
11286 "HAVE_SYMLINKAT",
11287#endif
11288
11289#ifdef HAVE_UNLINKAT
11290 "HAVE_UNLINKAT",
11291#endif
11292
11293#ifdef HAVE_UTIMENSAT
11294 "HAVE_UTIMENSAT",
11295#endif
11296
11297#ifdef MS_WINDOWS
11298 "MS_WINDOWS",
11299#endif
11300
11301 NULL
11302};
11303
11304
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011305PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011306INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011307{
Victor Stinner8c62be82010-05-06 00:08:46 +000011308 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011309 PyObject *list;
11310 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000011311
Brian Curtin52173d42010-12-02 18:29:18 +000011312#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011313 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011314#endif
11315
Victor Stinner8c62be82010-05-06 00:08:46 +000011316 m = PyModule_Create(&posixmodule);
11317 if (m == NULL)
11318 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011319
Victor Stinner8c62be82010-05-06 00:08:46 +000011320 /* Initialize environ dictionary */
11321 v = convertenviron();
11322 Py_XINCREF(v);
11323 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11324 return NULL;
11325 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011326
Victor Stinner8c62be82010-05-06 00:08:46 +000011327 if (all_ins(m))
11328 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011329
Victor Stinner8c62be82010-05-06 00:08:46 +000011330 if (setup_confname_tables(m))
11331 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011332
Victor Stinner8c62be82010-05-06 00:08:46 +000011333 Py_INCREF(PyExc_OSError);
11334 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011335
Guido van Rossumb3d39562000-01-31 18:41:26 +000011336#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011337 if (posix_putenv_garbage == NULL)
11338 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011339#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011340
Victor Stinner8c62be82010-05-06 00:08:46 +000011341 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011342#if defined(HAVE_WAITID) && !defined(__APPLE__)
11343 waitid_result_desc.name = MODNAME ".waitid_result";
11344 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
11345#endif
11346
Victor Stinner8c62be82010-05-06 00:08:46 +000011347 stat_result_desc.name = MODNAME ".stat_result";
11348 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11349 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11350 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
11351 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
11352 structseq_new = StatResultType.tp_new;
11353 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011354
Victor Stinner8c62be82010-05-06 00:08:46 +000011355 statvfs_result_desc.name = MODNAME ".statvfs_result";
11356 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011357#ifdef NEED_TICKS_PER_SECOND
11358# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011359 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011360# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011361 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011362# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011363 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011364# endif
11365#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011366
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050011367#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011368 sched_param_desc.name = MODNAME ".sched_param";
11369 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
11370 SchedParamType.tp_new = sched_param_new;
11371#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011372
11373 /* initialize TerminalSize_info */
11374 PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc);
Victor Stinner8c62be82010-05-06 00:08:46 +000011375 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011376#if defined(HAVE_WAITID) && !defined(__APPLE__)
11377 Py_INCREF((PyObject*) &WaitidResultType);
11378 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
11379#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011380 Py_INCREF((PyObject*) &StatResultType);
11381 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11382 Py_INCREF((PyObject*) &StatVFSResultType);
11383 PyModule_AddObject(m, "statvfs_result",
11384 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011385
11386#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011387 Py_INCREF(&SchedParamType);
11388 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011389#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011390
Larry Hastings605a62d2012-06-24 04:33:36 -070011391 times_result_desc.name = MODNAME ".times_result";
11392 PyStructSequence_InitType(&TimesResultType, &times_result_desc);
11393 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
11394
11395 uname_result_desc.name = MODNAME ".uname_result";
11396 PyStructSequence_InitType(&UnameResultType, &uname_result_desc);
11397 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
11398
Thomas Wouters477c8d52006-05-27 19:21:47 +000011399#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000011400 /*
11401 * Step 2 of weak-linking support on Mac OS X.
11402 *
11403 * The code below removes functions that are not available on the
11404 * currently active platform.
11405 *
11406 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070011407 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000011408 * OSX 10.4.
11409 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011410#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011411 if (fstatvfs == NULL) {
11412 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
11413 return NULL;
11414 }
11415 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011416#endif /* HAVE_FSTATVFS */
11417
11418#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011419 if (statvfs == NULL) {
11420 if (PyObject_DelAttrString(m, "statvfs") == -1) {
11421 return NULL;
11422 }
11423 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011424#endif /* HAVE_STATVFS */
11425
11426# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011427 if (lchown == NULL) {
11428 if (PyObject_DelAttrString(m, "lchown") == -1) {
11429 return NULL;
11430 }
11431 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011432#endif /* HAVE_LCHOWN */
11433
11434
11435#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011436
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020011437 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011438 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
11439
Larry Hastings6fe20b32012-04-19 15:07:49 -070011440 billion = PyLong_FromLong(1000000000);
11441 if (!billion)
11442 return NULL;
11443
Larry Hastings9cf065c2012-06-22 16:30:09 -070011444 /* suppress "function not used" warnings */
11445 {
11446 int ignored;
11447 fd_specified("", -1);
11448 follow_symlinks_specified("", 1);
11449 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
11450 dir_fd_converter(Py_None, &ignored);
11451 dir_fd_unavailable(Py_None, &ignored);
11452 }
11453
11454 /*
11455 * provide list of locally available functions
11456 * so os.py can populate support_* lists
11457 */
11458 list = PyList_New(0);
11459 if (!list)
11460 return NULL;
11461 for (trace = have_functions; *trace; trace++) {
11462 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
11463 if (!unicode)
11464 return NULL;
11465 if (PyList_Append(list, unicode))
11466 return NULL;
11467 Py_DECREF(unicode);
11468 }
11469 PyModule_AddObject(m, "_have_functions", list);
11470
11471 initialized = 1;
11472
Victor Stinner8c62be82010-05-06 00:08:46 +000011473 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011474
Guido van Rossumb6775db1994-08-01 11:34:53 +000011475}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011476
11477#ifdef __cplusplus
11478}
11479#endif