blob: 064d162e01070f8203c395437a0f93d3bc51163b [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"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000026
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000027#if defined(__VMS)
Victor Stinnerb90db4c2011-04-26 22:48:24 +020028# error "PEP 11: VMS is now unsupported, code will be removed in Python 3.4"
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000029# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000030#endif /* defined(__VMS) */
31
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000032#ifdef __cplusplus
33extern "C" {
34#endif
35
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000036PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000037"This module provides access to operating system functionality that is\n\
38standardized by the C Standard and the POSIX standard (a thinly\n\
39disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000040corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000041
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000042
Ross Lagerwall4d076da2011-03-18 06:56:53 +020043#ifdef HAVE_SYS_UIO_H
44#include <sys/uio.h>
45#endif
46
Thomas Wouters0e3f5912006-08-11 14:57:12 +000047#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000048#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000049#endif /* HAVE_SYS_TYPES_H */
50
51#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000052#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000053#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000054
Guido van Rossum36bc6801995-06-14 22:54:23 +000055#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000056#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000057#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000058
Thomas Wouters0e3f5912006-08-11 14:57:12 +000059#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000060#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000061#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000062
Guido van Rossumb6775db1994-08-01 11:34:53 +000063#ifdef HAVE_FCNTL_H
64#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000065#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000066
Guido van Rossuma6535fd2001-10-18 19:44:10 +000067#ifdef HAVE_GRP_H
68#include <grp.h>
69#endif
70
Barry Warsaw5676bd12003-01-07 20:57:09 +000071#ifdef HAVE_SYSEXITS_H
72#include <sysexits.h>
73#endif /* HAVE_SYSEXITS_H */
74
Anthony Baxter8a560de2004-10-13 15:30:56 +000075#ifdef HAVE_SYS_LOADAVG_H
76#include <sys/loadavg.h>
77#endif
78
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000079#ifdef HAVE_LANGINFO_H
80#include <langinfo.h>
81#endif
82
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000083#ifdef HAVE_SYS_SENDFILE_H
84#include <sys/sendfile.h>
85#endif
86
Benjamin Peterson94b580d2011-08-02 17:30:04 -050087#ifdef HAVE_SCHED_H
88#include <sched.h>
89#endif
90
Benjamin Peterson2dbda072012-03-16 10:12:55 -050091#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -050092#undef HAVE_SCHED_SETAFFINITY
93#endif
94
Benjamin Peterson9428d532011-09-14 11:45:52 -040095#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__)
96#define USE_XATTRS
97#endif
98
99#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400100#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400101#endif
102
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000103#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
104#ifdef HAVE_SYS_SOCKET_H
105#include <sys/socket.h>
106#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000107#endif
108
Victor Stinner8b905bd2011-10-25 13:34:04 +0200109#ifdef HAVE_DLFCN_H
110#include <dlfcn.h>
111#endif
112
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100113#if defined(MS_WINDOWS)
114# define TERMSIZE_USE_CONIO
115#elif defined(HAVE_SYS_IOCTL_H)
116# include <sys/ioctl.h>
117# if defined(HAVE_TERMIOS_H)
118# include <termios.h>
119# endif
120# if defined(TIOCGWINSZ)
121# define TERMSIZE_USE_IOCTL
122# endif
123#endif /* MS_WINDOWS */
124
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000125/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000126/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000127#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000128#define HAVE_GETCWD 1
129#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000130#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000131#include <process.h>
132#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000133#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000134#define HAVE_EXECV 1
135#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000136#define HAVE_OPENDIR 1
137#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000138#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000139#define HAVE_WAIT 1
140#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000141#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000142#define HAVE_GETCWD 1
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000143#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000144#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000145#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000146#define HAVE_EXECV 1
147#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000148#define HAVE_SYSTEM 1
149#define HAVE_CWAIT 1
150#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000151#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000152#else
Jesus Ceaab70e2a2012-10-05 01:48:08 +0200153#if defined(__VMS)
154/* Everything needed is defined in vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000155#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000156/* Unix functions that the configure script doesn't check for */
157#define HAVE_EXECV 1
158#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000159#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000160#define HAVE_FORK1 1
161#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000162#define HAVE_GETCWD 1
163#define HAVE_GETEGID 1
164#define HAVE_GETEUID 1
165#define HAVE_GETGID 1
166#define HAVE_GETPPID 1
167#define HAVE_GETUID 1
168#define HAVE_KILL 1
169#define HAVE_OPENDIR 1
170#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000171#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000172#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000173#define HAVE_TTYNAME 1
Jesus Ceaab70e2a2012-10-05 01:48:08 +0200174#endif /* __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000175#endif /* _MSC_VER */
176#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000177#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000178
Victor Stinnera2f7c002012-02-08 03:36:25 +0100179
180
181
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000182#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000183
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000184#if defined(__sgi)&&_COMPILER_VERSION>=700
185/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
186 (default) */
187extern char *ctermid_r(char *);
188#endif
189
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000190#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000191#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000192extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000193#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000194#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000195extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000196#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000197extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000198#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000199#endif
200#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000201extern int chdir(char *);
202extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000203#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000204extern int chdir(const char *);
205extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000206#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000207#ifdef __BORLANDC__
208extern int chmod(const char *, int);
209#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000210extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000211#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000212/*#ifdef HAVE_FCHMOD
213extern int fchmod(int, mode_t);
214#endif*/
215/*#ifdef HAVE_LCHMOD
216extern int lchmod(const char *, mode_t);
217#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000218extern int chown(const char *, uid_t, gid_t);
219extern char *getcwd(char *, int);
220extern char *strerror(int);
221extern int link(const char *, const char *);
222extern int rename(const char *, const char *);
223extern int stat(const char *, struct stat *);
224extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000225#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000226extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000227#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000228#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000229extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000230#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000231#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000232
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000233#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000234
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235#ifdef HAVE_UTIME_H
236#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000237#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000238
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000239#ifdef HAVE_SYS_UTIME_H
240#include <sys/utime.h>
241#define HAVE_UTIME_H /* pretend we do for the rest of this file */
242#endif /* HAVE_SYS_UTIME_H */
243
Guido van Rossumb6775db1994-08-01 11:34:53 +0000244#ifdef HAVE_SYS_TIMES_H
245#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000246#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247
248#ifdef HAVE_SYS_PARAM_H
249#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000250#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251
252#ifdef HAVE_SYS_UTSNAME_H
253#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000254#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000255
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000256#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000258#define NAMLEN(dirent) strlen((dirent)->d_name)
259#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000260#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000261#include <direct.h>
262#define NAMLEN(dirent) strlen((dirent)->d_name)
263#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000264#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000265#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000266#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000267#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000268#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000269#endif
270#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000272#endif
273#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000274#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000275#endif
276#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000277
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000278#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000279#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000280#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000281#endif
282#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000283#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000284#endif
285#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000286#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000287#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000288#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000289#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000290#endif
291#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000292#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000293#endif
294#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000295#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000296#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000297#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000298#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000299#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000300#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000301#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000302#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
303#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000304static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000305#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000306#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000307
Tim Petersbc2e10e2002-03-03 23:17:02 +0000308#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000309#if defined(PATH_MAX) && PATH_MAX > 1024
310#define MAXPATHLEN PATH_MAX
311#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000312#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000313#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000314#endif /* MAXPATHLEN */
315
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000316#ifdef UNION_WAIT
317/* Emulate some macros on systems that have a union instead of macros */
318
319#ifndef WIFEXITED
320#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
321#endif
322
323#ifndef WEXITSTATUS
324#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
325#endif
326
327#ifndef WTERMSIG
328#define WTERMSIG(u_wait) ((u_wait).w_termsig)
329#endif
330
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000331#define WAIT_TYPE union wait
332#define WAIT_STATUS_INT(s) (s.w_status)
333
334#else /* !UNION_WAIT */
335#define WAIT_TYPE int
336#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000337#endif /* UNION_WAIT */
338
Greg Wardb48bc172000-03-01 21:51:56 +0000339/* Don't use the "_r" form if we don't need it (also, won't have a
340 prototype for it, at least on Solaris -- maybe others as well?). */
341#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
342#define USE_CTERMID_R
343#endif
344
Fred Drake699f3522000-06-29 21:12:41 +0000345/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000346#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000347#undef FSTAT
348#undef STRUCT_STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000349#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000350# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700351# define LSTAT win32_lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000352# define FSTAT win32_fstat
353# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000354#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000355# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700356# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000357# define FSTAT fstat
358# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000359#endif
360
Tim Peters11b23062003-04-23 02:39:17 +0000361#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000362#include <sys/mkdev.h>
363#else
364#if defined(MAJOR_IN_SYSMACROS)
365#include <sys/sysmacros.h>
366#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000367#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
368#include <sys/mkdev.h>
369#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000370#endif
Fred Drake699f3522000-06-29 21:12:41 +0000371
Larry Hastings9cf065c2012-06-22 16:30:09 -0700372
373#ifdef MS_WINDOWS
374static int
375win32_warn_bytes_api()
376{
377 return PyErr_WarnEx(PyExc_DeprecationWarning,
378 "The Windows bytes API has been deprecated, "
379 "use Unicode filenames instead",
380 1);
381}
382#endif
383
384
385#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400386/*
387 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
388 * without the int cast, the value gets interpreted as uint (4291925331),
389 * which doesn't play nicely with all the initializer lines in this file that
390 * look like this:
391 * int dir_fd = DEFAULT_DIR_FD;
392 */
393#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700394#else
395#define DEFAULT_DIR_FD (-100)
396#endif
397
398static int
399_fd_converter(PyObject *o, int *p, int default_value) {
400 long long_value;
401 if (o == Py_None) {
402 *p = default_value;
403 return 1;
404 }
405 if (PyFloat_Check(o)) {
406 PyErr_SetString(PyExc_TypeError,
407 "integer argument expected, got float" );
408 return 0;
409 }
410 long_value = PyLong_AsLong(o);
411 if (long_value == -1 && PyErr_Occurred())
412 return 0;
413 if (long_value > INT_MAX) {
414 PyErr_SetString(PyExc_OverflowError,
415 "signed integer is greater than maximum");
416 return 0;
417 }
418 if (long_value < INT_MIN) {
419 PyErr_SetString(PyExc_OverflowError,
420 "signed integer is less than minimum");
421 return 0;
422 }
423 *p = (int)long_value;
424 return 1;
425}
426
427static int
428dir_fd_converter(PyObject *o, void *p) {
429 return _fd_converter(o, (int *)p, DEFAULT_DIR_FD);
430}
431
432
433
434/*
435 * A PyArg_ParseTuple "converter" function
436 * that handles filesystem paths in the manner
437 * preferred by the os module.
438 *
439 * path_converter accepts (Unicode) strings and their
440 * subclasses, and bytes and their subclasses. What
441 * it does with the argument depends on the platform:
442 *
443 * * On Windows, if we get a (Unicode) string we
444 * extract the wchar_t * and return it; if we get
445 * bytes we extract the char * and return that.
446 *
447 * * On all other platforms, strings are encoded
448 * to bytes using PyUnicode_FSConverter, then we
449 * extract the char * from the bytes object and
450 * return that.
451 *
452 * path_converter also optionally accepts signed
453 * integers (representing open file descriptors) instead
454 * of path strings.
455 *
456 * Input fields:
457 * path.nullable
458 * If nonzero, the path is permitted to be None.
459 * path.allow_fd
460 * If nonzero, the path is permitted to be a file handle
461 * (a signed int) instead of a string.
462 * path.function_name
463 * If non-NULL, path_converter will use that as the name
464 * of the function in error messages.
465 * (If path.argument_name is NULL it omits the function name.)
466 * path.argument_name
467 * If non-NULL, path_converter will use that as the name
468 * of the parameter in error messages.
469 * (If path.argument_name is NULL it uses "path".)
470 *
471 * Output fields:
472 * path.wide
473 * Points to the path if it was expressed as Unicode
474 * and was not encoded. (Only used on Windows.)
475 * path.narrow
476 * Points to the path if it was expressed as bytes,
477 * or it was Unicode and was encoded to bytes.
478 * path.fd
479 * Contains a file descriptor if path.accept_fd was true
480 * and the caller provided a signed integer instead of any
481 * sort of string.
482 *
483 * WARNING: if your "path" parameter is optional, and is
484 * unspecified, path_converter will never get called.
485 * So if you set allow_fd, you *MUST* initialize path.fd = -1
486 * yourself!
487 * path.length
488 * The length of the path in characters, if specified as
489 * a string.
490 * path.object
491 * The original object passed in.
492 * path.cleanup
493 * For internal use only. May point to a temporary object.
494 * (Pay no attention to the man behind the curtain.)
495 *
496 * At most one of path.wide or path.narrow will be non-NULL.
497 * If path was None and path.nullable was set,
498 * or if path was an integer and path.allow_fd was set,
499 * both path.wide and path.narrow will be NULL
500 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200501 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700502 * path_converter takes care to not write to the path_t
503 * unless it's successful. However it must reset the
504 * "cleanup" field each time it's called.
505 *
506 * Use as follows:
507 * path_t path;
508 * memset(&path, 0, sizeof(path));
509 * PyArg_ParseTuple(args, "O&", path_converter, &path);
510 * // ... use values from path ...
511 * path_cleanup(&path);
512 *
513 * (Note that if PyArg_Parse fails you don't need to call
514 * path_cleanup(). However it is safe to do so.)
515 */
516typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100517 const char *function_name;
518 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700519 int nullable;
520 int allow_fd;
521 wchar_t *wide;
522 char *narrow;
523 int fd;
524 Py_ssize_t length;
525 PyObject *object;
526 PyObject *cleanup;
527} path_t;
528
529static void
530path_cleanup(path_t *path) {
531 if (path->cleanup) {
532 Py_DECREF(path->cleanup);
533 path->cleanup = NULL;
534 }
535}
536
537static int
538path_converter(PyObject *o, void *p) {
539 path_t *path = (path_t *)p;
540 PyObject *unicode, *bytes;
541 Py_ssize_t length;
542 char *narrow;
543
544#define FORMAT_EXCEPTION(exc, fmt) \
545 PyErr_Format(exc, "%s%s" fmt, \
546 path->function_name ? path->function_name : "", \
547 path->function_name ? ": " : "", \
548 path->argument_name ? path->argument_name : "path")
549
550 /* Py_CLEANUP_SUPPORTED support */
551 if (o == NULL) {
552 path_cleanup(path);
553 return 1;
554 }
555
556 /* ensure it's always safe to call path_cleanup() */
557 path->cleanup = NULL;
558
559 if (o == Py_None) {
560 if (!path->nullable) {
561 FORMAT_EXCEPTION(PyExc_TypeError,
562 "can't specify None for %s argument");
563 return 0;
564 }
565 path->wide = NULL;
566 path->narrow = NULL;
567 path->length = 0;
568 path->object = o;
569 path->fd = -1;
570 return 1;
571 }
572
573 unicode = PyUnicode_FromObject(o);
574 if (unicode) {
575#ifdef MS_WINDOWS
576 wchar_t *wide;
577 length = PyUnicode_GET_SIZE(unicode);
578 if (length > 32767) {
579 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
580 Py_DECREF(unicode);
581 return 0;
582 }
583
584 wide = PyUnicode_AsUnicode(unicode);
585 if (!wide) {
586 Py_DECREF(unicode);
587 return 0;
588 }
589
590 path->wide = wide;
591 path->narrow = NULL;
592 path->length = length;
593 path->object = o;
594 path->fd = -1;
595 path->cleanup = unicode;
596 return Py_CLEANUP_SUPPORTED;
597#else
598 int converted = PyUnicode_FSConverter(unicode, &bytes);
599 Py_DECREF(unicode);
600 if (!converted)
601 bytes = NULL;
602#endif
603 }
604 else {
605 PyErr_Clear();
606 bytes = PyBytes_FromObject(o);
607 if (!bytes) {
608 PyErr_Clear();
609 if (path->allow_fd) {
610 int fd;
611 /*
612 * note: _fd_converter always permits None.
613 * but we've already done our None check.
614 * so o cannot be None at this point.
615 */
616 int result = _fd_converter(o, &fd, -1);
617 if (result) {
618 path->wide = NULL;
619 path->narrow = NULL;
620 path->length = 0;
621 path->object = o;
622 path->fd = fd;
623 return result;
624 }
625 }
626 }
627 }
628
629 if (!bytes) {
630 if (!PyErr_Occurred())
631 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
632 return 0;
633 }
634
635#ifdef MS_WINDOWS
636 if (win32_warn_bytes_api()) {
637 Py_DECREF(bytes);
638 return 0;
639 }
640#endif
641
642 length = PyBytes_GET_SIZE(bytes);
643#ifdef MS_WINDOWS
644 if (length > MAX_PATH) {
645 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
646 Py_DECREF(bytes);
647 return 0;
648 }
649#endif
650
651 narrow = PyBytes_AS_STRING(bytes);
652 if (length != strlen(narrow)) {
653 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s");
654 Py_DECREF(bytes);
655 return 0;
656 }
657
658 path->wide = NULL;
659 path->narrow = narrow;
660 path->length = length;
661 path->object = o;
662 path->fd = -1;
663 path->cleanup = bytes;
664 return Py_CLEANUP_SUPPORTED;
665}
666
667static void
668argument_unavailable_error(char *function_name, char *argument_name) {
669 PyErr_Format(PyExc_NotImplementedError,
670 "%s%s%s unavailable on this platform",
671 (function_name != NULL) ? function_name : "",
672 (function_name != NULL) ? ": ": "",
673 argument_name);
674}
675
676static int
677dir_fd_unavailable(PyObject *o, void *p) {
678 int *dir_fd = (int *)p;
679 int return_value = _fd_converter(o, dir_fd, DEFAULT_DIR_FD);
680 if (!return_value)
681 return 0;
682 if (*dir_fd == DEFAULT_DIR_FD)
683 return 1;
684 argument_unavailable_error(NULL, "dir_fd");
685 return 0;
686}
687
688static int
689fd_specified(char *function_name, int fd) {
690 if (fd == -1)
691 return 0;
692
693 argument_unavailable_error(function_name, "fd");
694 return 1;
695}
696
697static int
698follow_symlinks_specified(char *function_name, int follow_symlinks) {
699 if (follow_symlinks)
700 return 0;
701
702 argument_unavailable_error(function_name, "follow_symlinks");
703 return 1;
704}
705
706static int
707path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
708 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
709 PyErr_Format(PyExc_ValueError,
710 "%s: can't specify dir_fd without matching path",
711 function_name);
712 return 1;
713 }
714 return 0;
715}
716
717static int
718dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
719 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
720 PyErr_Format(PyExc_ValueError,
721 "%s: can't specify both dir_fd and fd",
722 function_name);
723 return 1;
724 }
725 return 0;
726}
727
728static int
729fd_and_follow_symlinks_invalid(char *function_name, int fd,
730 int follow_symlinks) {
731 if ((fd > 0) && (!follow_symlinks)) {
732 PyErr_Format(PyExc_ValueError,
733 "%s: cannot use fd and follow_symlinks together",
734 function_name);
735 return 1;
736 }
737 return 0;
738}
739
740static int
741dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
742 int follow_symlinks) {
743 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
744 PyErr_Format(PyExc_ValueError,
745 "%s: cannot use dir_fd and follow_symlinks together",
746 function_name);
747 return 1;
748 }
749 return 0;
750}
751
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200752/* A helper used by a number of POSIX-only functions */
753#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +0000754static int
755_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000756{
757#if !defined(HAVE_LARGEFILE_SUPPORT)
758 *((off_t*)addr) = PyLong_AsLong(arg);
759#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +0000760 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000761#endif
762 if (PyErr_Occurred())
763 return 0;
764 return 1;
765}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200766#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000767
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000768#if defined _MSC_VER && _MSC_VER >= 1400
769/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
Andrew Svetlov737fb892012-12-18 21:14:22 +0200770 * valid and raise an assertion if it isn't.
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000771 * Normally, an invalid fd is likely to be a C program error and therefore
772 * an assertion can be useful, but it does contradict the POSIX standard
773 * which for write(2) states:
774 * "Otherwise, -1 shall be returned and errno set to indicate the error."
775 * "[EBADF] The fildes argument is not a valid file descriptor open for
776 * writing."
777 * Furthermore, python allows the user to enter any old integer
778 * as a fd and should merely raise a python exception on error.
779 * The Microsoft CRT doesn't provide an official way to check for the
780 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000781 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000782 * internal structures involved.
783 * The structures below must be updated for each version of visual studio
784 * according to the file internal.h in the CRT source, until MS comes
785 * up with a less hacky way to do this.
786 * (all of this is to avoid globally modifying the CRT behaviour using
787 * _set_invalid_parameter_handler() and _CrtSetReportMode())
788 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000789/* The actual size of the structure is determined at runtime.
790 * Only the first items must be present.
791 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000792typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000793 intptr_t osfhnd;
794 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000795} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000796
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000797extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000798#define IOINFO_L2E 5
799#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
800#define IOINFO_ARRAYS 64
801#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
802#define FOPEN 0x01
803#define _NO_CONSOLE_FILENO (intptr_t)-2
804
805/* This function emulates what the windows CRT does to validate file handles */
806int
807_PyVerify_fd(int fd)
808{
Victor Stinner8c62be82010-05-06 00:08:46 +0000809 const int i1 = fd >> IOINFO_L2E;
810 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000811
Antoine Pitrou22e41552010-08-15 18:07:50 +0000812 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000813
Victor Stinner8c62be82010-05-06 00:08:46 +0000814 /* Determine the actual size of the ioinfo structure,
815 * as used by the CRT loaded in memory
816 */
817 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
818 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
819 }
820 if (sizeof_ioinfo == 0) {
821 /* This should not happen... */
822 goto fail;
823 }
824
825 /* See that it isn't a special CLEAR fileno */
826 if (fd != _NO_CONSOLE_FILENO) {
827 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
828 * we check pointer validity and other info
829 */
830 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
831 /* finally, check that the file is open */
832 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
833 if (info->osfile & FOPEN) {
834 return 1;
835 }
836 }
837 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000838 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000839 errno = EBADF;
840 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000841}
842
843/* the special case of checking dup2. The target fd must be in a sensible range */
844static int
845_PyVerify_fd_dup2(int fd1, int fd2)
846{
Victor Stinner8c62be82010-05-06 00:08:46 +0000847 if (!_PyVerify_fd(fd1))
848 return 0;
849 if (fd2 == _NO_CONSOLE_FILENO)
850 return 0;
851 if ((unsigned)fd2 < _NHANDLE_)
852 return 1;
853 else
854 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000855}
856#else
857/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
858#define _PyVerify_fd_dup2(A, B) (1)
859#endif
860
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000861#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +0000862/* The following structure was copied from
863 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
864 include doesn't seem to be present in the Windows SDK (at least as included
865 with Visual Studio Express). */
866typedef struct _REPARSE_DATA_BUFFER {
867 ULONG ReparseTag;
868 USHORT ReparseDataLength;
869 USHORT Reserved;
870 union {
871 struct {
872 USHORT SubstituteNameOffset;
873 USHORT SubstituteNameLength;
874 USHORT PrintNameOffset;
875 USHORT PrintNameLength;
876 ULONG Flags;
877 WCHAR PathBuffer[1];
878 } SymbolicLinkReparseBuffer;
879
880 struct {
881 USHORT SubstituteNameOffset;
882 USHORT SubstituteNameLength;
883 USHORT PrintNameOffset;
884 USHORT PrintNameLength;
885 WCHAR PathBuffer[1];
886 } MountPointReparseBuffer;
887
888 struct {
889 UCHAR DataBuffer[1];
890 } GenericReparseBuffer;
891 };
892} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
893
894#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
895 GenericReparseBuffer)
896#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
897
898static int
Brian Curtind25aef52011-06-13 15:16:04 -0500899win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +0000900{
901 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
902 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
903 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000904
905 if (0 == DeviceIoControl(
906 reparse_point_handle,
907 FSCTL_GET_REPARSE_POINT,
908 NULL, 0, /* in buffer */
909 target_buffer, sizeof(target_buffer),
910 &n_bytes_returned,
911 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -0500912 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000913
914 if (reparse_tag)
915 *reparse_tag = rdb->ReparseTag;
916
Brian Curtind25aef52011-06-13 15:16:04 -0500917 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000918}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100919
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000920#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +0000921
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000922/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000923#ifdef WITH_NEXT_FRAMEWORK
924/* On Darwin/MacOSX a shared library or framework has no access to
925** environ directly, we must obtain it with _NSGetEnviron().
926*/
927#include <crt_externs.h>
928static char **environ;
929#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000930extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000931#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000932
Barry Warsaw53699e91996-12-10 23:23:01 +0000933static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000934convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000935{
Victor Stinner8c62be82010-05-06 00:08:46 +0000936 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000937#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000938 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000939#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000940 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000941#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000942
Victor Stinner8c62be82010-05-06 00:08:46 +0000943 d = PyDict_New();
944 if (d == NULL)
945 return NULL;
946#ifdef WITH_NEXT_FRAMEWORK
947 if (environ == NULL)
948 environ = *_NSGetEnviron();
949#endif
950#ifdef MS_WINDOWS
951 /* _wenviron must be initialized in this way if the program is started
952 through main() instead of wmain(). */
953 _wgetenv(L"");
954 if (_wenviron == NULL)
955 return d;
956 /* This part ignores errors */
957 for (e = _wenviron; *e != NULL; e++) {
958 PyObject *k;
959 PyObject *v;
960 wchar_t *p = wcschr(*e, L'=');
961 if (p == NULL)
962 continue;
963 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
964 if (k == NULL) {
965 PyErr_Clear();
966 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000967 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000968 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
969 if (v == NULL) {
970 PyErr_Clear();
971 Py_DECREF(k);
972 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000973 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000974 if (PyDict_GetItem(d, k) == NULL) {
975 if (PyDict_SetItem(d, k, v) != 0)
976 PyErr_Clear();
977 }
978 Py_DECREF(k);
979 Py_DECREF(v);
980 }
981#else
982 if (environ == NULL)
983 return d;
984 /* This part ignores errors */
985 for (e = environ; *e != NULL; e++) {
986 PyObject *k;
987 PyObject *v;
988 char *p = strchr(*e, '=');
989 if (p == NULL)
990 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +0000991 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +0000992 if (k == NULL) {
993 PyErr_Clear();
994 continue;
995 }
Victor Stinner84ae1182010-05-06 22:05:07 +0000996 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +0000997 if (v == NULL) {
998 PyErr_Clear();
999 Py_DECREF(k);
1000 continue;
1001 }
1002 if (PyDict_GetItem(d, k) == NULL) {
1003 if (PyDict_SetItem(d, k, v) != 0)
1004 PyErr_Clear();
1005 }
1006 Py_DECREF(k);
1007 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001008 }
1009#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001010 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001011}
1012
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001013/* Set a POSIX-specific error from errno, and return NULL */
1014
Barry Warsawd58d7641998-07-23 16:14:40 +00001015static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001016posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001017{
Victor Stinner8c62be82010-05-06 00:08:46 +00001018 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001019}
Mark Hammondef8b6542001-05-13 08:04:26 +00001020
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001021#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001022static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001023win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001024{
Victor Stinner8c62be82010-05-06 00:08:46 +00001025 /* XXX We should pass the function name along in the future.
1026 (winreg.c also wants to pass the function name.)
1027 This would however require an additional param to the
1028 Windows error object, which is non-trivial.
1029 */
1030 errno = GetLastError();
1031 if (filename)
1032 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1033 else
1034 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001035}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001036
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001037static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001038win32_error_object(char* function, PyObject* filename)
1039{
1040 /* XXX - see win32_error for comments on 'function' */
1041 errno = GetLastError();
1042 if (filename)
1043 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001044 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001045 errno,
1046 filename);
1047 else
1048 return PyErr_SetFromWindowsErr(errno);
1049}
1050
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001051#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001052
Larry Hastings9cf065c2012-06-22 16:30:09 -07001053static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001054path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001055{
1056#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001057 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1058 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001059#else
Victor Stinner292c8352012-10-30 02:17:38 +01001060 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001061#endif
1062}
1063
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001064/* POSIX generic methods */
1065
Barry Warsaw53699e91996-12-10 23:23:01 +00001066static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001067posix_fildes(PyObject *fdobj, int (*func)(int))
1068{
Victor Stinner8c62be82010-05-06 00:08:46 +00001069 int fd;
1070 int res;
1071 fd = PyObject_AsFileDescriptor(fdobj);
1072 if (fd < 0)
1073 return NULL;
1074 if (!_PyVerify_fd(fd))
1075 return posix_error();
1076 Py_BEGIN_ALLOW_THREADS
1077 res = (*func)(fd);
1078 Py_END_ALLOW_THREADS
1079 if (res < 0)
1080 return posix_error();
1081 Py_INCREF(Py_None);
1082 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001083}
Guido van Rossum21142a01999-01-08 21:05:37 +00001084
1085static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001086posix_1str(const char *func_name, PyObject *args, char *format,
1087 int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001088{
Victor Stinner292c8352012-10-30 02:17:38 +01001089 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001090 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01001091 memset(&path, 0, sizeof(path));
1092 path.function_name = func_name;
Victor Stinner8c62be82010-05-06 00:08:46 +00001093 if (!PyArg_ParseTuple(args, format,
Victor Stinner292c8352012-10-30 02:17:38 +01001094 path_converter, &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00001095 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001096 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001097 res = (*func)(path.narrow);
Victor Stinner8c62be82010-05-06 00:08:46 +00001098 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001099 if (res < 0) {
1100 path_error(&path);
1101 path_cleanup(&path);
1102 return NULL;
1103 }
1104 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001105 Py_INCREF(Py_None);
1106 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001107}
1108
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001109
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001110#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001111/* This is a reimplementation of the C library's chdir function,
1112 but one that produces Win32 errors instead of DOS error codes.
1113 chdir is essentially a wrapper around SetCurrentDirectory; however,
1114 it also needs to set "magic" environment variables indicating
1115 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001116static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001117win32_chdir(LPCSTR path)
1118{
Victor Stinner8c62be82010-05-06 00:08:46 +00001119 char new_path[MAX_PATH+1];
1120 int result;
1121 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001122
Victor Stinner8c62be82010-05-06 00:08:46 +00001123 if(!SetCurrentDirectoryA(path))
1124 return FALSE;
1125 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
1126 if (!result)
1127 return FALSE;
1128 /* In the ANSI API, there should not be any paths longer
1129 than MAX_PATH. */
1130 assert(result <= MAX_PATH+1);
1131 if (strncmp(new_path, "\\\\", 2) == 0 ||
1132 strncmp(new_path, "//", 2) == 0)
1133 /* UNC path, nothing to do. */
1134 return TRUE;
1135 env[1] = new_path[0];
1136 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001137}
1138
1139/* The Unicode version differs from the ANSI version
1140 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001141static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001142win32_wchdir(LPCWSTR path)
1143{
Victor Stinner8c62be82010-05-06 00:08:46 +00001144 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
1145 int result;
1146 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001147
Victor Stinner8c62be82010-05-06 00:08:46 +00001148 if(!SetCurrentDirectoryW(path))
1149 return FALSE;
1150 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
1151 if (!result)
1152 return FALSE;
1153 if (result > MAX_PATH+1) {
1154 new_path = malloc(result * sizeof(wchar_t));
1155 if (!new_path) {
1156 SetLastError(ERROR_OUTOFMEMORY);
1157 return FALSE;
1158 }
1159 result = GetCurrentDirectoryW(result, new_path);
1160 if (!result) {
1161 free(new_path);
1162 return FALSE;
1163 }
1164 }
1165 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1166 wcsncmp(new_path, L"//", 2) == 0)
1167 /* UNC path, nothing to do. */
1168 return TRUE;
1169 env[1] = new_path[0];
1170 result = SetEnvironmentVariableW(env, new_path);
1171 if (new_path != _new_path)
1172 free(new_path);
1173 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001174}
1175#endif
1176
Martin v. Löwis14694662006-02-03 12:54:16 +00001177#ifdef MS_WINDOWS
1178/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1179 - time stamps are restricted to second resolution
1180 - file modification times suffer from forth-and-back conversions between
1181 UTC and local time
1182 Therefore, we implement our own stat, based on the Win32 API directly.
1183*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001184#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001185
1186struct win32_stat{
1187 int st_dev;
1188 __int64 st_ino;
1189 unsigned short st_mode;
1190 int st_nlink;
1191 int st_uid;
1192 int st_gid;
1193 int st_rdev;
1194 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001195 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001196 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001197 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001198 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001199 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001200 int st_ctime_nsec;
1201};
1202
1203static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1204
1205static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001206FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001207{
Victor Stinner8c62be82010-05-06 00:08:46 +00001208 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1209 /* Cannot simply cast and dereference in_ptr,
1210 since it might not be aligned properly */
1211 __int64 in;
1212 memcpy(&in, in_ptr, sizeof(in));
1213 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001214 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001215}
1216
Thomas Wouters477c8d52006-05-27 19:21:47 +00001217static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001218time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001219{
Victor Stinner8c62be82010-05-06 00:08:46 +00001220 /* XXX endianness */
1221 __int64 out;
1222 out = time_in + secs_between_epochs;
1223 out = out * 10000000 + nsec_in / 100;
1224 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001225}
1226
Martin v. Löwis14694662006-02-03 12:54:16 +00001227/* Below, we *know* that ugo+r is 0444 */
1228#if _S_IREAD != 0400
1229#error Unsupported C library
1230#endif
1231static int
1232attributes_to_mode(DWORD attr)
1233{
Victor Stinner8c62be82010-05-06 00:08:46 +00001234 int m = 0;
1235 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1236 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1237 else
1238 m |= _S_IFREG;
1239 if (attr & FILE_ATTRIBUTE_READONLY)
1240 m |= 0444;
1241 else
1242 m |= 0666;
1243 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001244}
1245
1246static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001247attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001248{
Victor Stinner8c62be82010-05-06 00:08:46 +00001249 memset(result, 0, sizeof(*result));
1250 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1251 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
Brian Curtin490b32a2012-12-26 07:03:03 -06001252 result->st_dev = info->dwVolumeSerialNumber;
1253 result->st_rdev = result->st_dev;
Victor Stinner8c62be82010-05-06 00:08:46 +00001254 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1255 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1256 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001257 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001258 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001259 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1260 /* first clear the S_IFMT bits */
1261 result->st_mode ^= (result->st_mode & 0170000);
1262 /* now set the bits that make this a symlink */
1263 result->st_mode |= 0120000;
1264 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001265
Victor Stinner8c62be82010-05-06 00:08:46 +00001266 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001267}
1268
Guido van Rossumd8faa362007-04-27 19:54:29 +00001269static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001270attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001271{
Victor Stinner8c62be82010-05-06 00:08:46 +00001272 HANDLE hFindFile;
1273 WIN32_FIND_DATAA FileData;
1274 hFindFile = FindFirstFileA(pszFile, &FileData);
1275 if (hFindFile == INVALID_HANDLE_VALUE)
1276 return FALSE;
1277 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001278 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001279 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001280 info->dwFileAttributes = FileData.dwFileAttributes;
1281 info->ftCreationTime = FileData.ftCreationTime;
1282 info->ftLastAccessTime = FileData.ftLastAccessTime;
1283 info->ftLastWriteTime = FileData.ftLastWriteTime;
1284 info->nFileSizeHigh = FileData.nFileSizeHigh;
1285 info->nFileSizeLow = FileData.nFileSizeLow;
1286/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001287 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1288 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001289 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001290}
1291
1292static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001293attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001294{
Victor Stinner8c62be82010-05-06 00:08:46 +00001295 HANDLE hFindFile;
1296 WIN32_FIND_DATAW FileData;
1297 hFindFile = FindFirstFileW(pszFile, &FileData);
1298 if (hFindFile == INVALID_HANDLE_VALUE)
1299 return FALSE;
1300 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001301 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001302 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001303 info->dwFileAttributes = FileData.dwFileAttributes;
1304 info->ftCreationTime = FileData.ftCreationTime;
1305 info->ftLastAccessTime = FileData.ftLastAccessTime;
1306 info->ftLastWriteTime = FileData.ftLastWriteTime;
1307 info->nFileSizeHigh = FileData.nFileSizeHigh;
1308 info->nFileSizeLow = FileData.nFileSizeLow;
1309/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001310 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1311 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001312 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001313}
1314
Brian Curtind25aef52011-06-13 15:16:04 -05001315/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001316static int has_GetFinalPathNameByHandle = -1;
Brian Curtind25aef52011-06-13 15:16:04 -05001317static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1318 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001319static int
Brian Curtind25aef52011-06-13 15:16:04 -05001320check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001321{
Brian Curtind25aef52011-06-13 15:16:04 -05001322 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001323 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1324 DWORD);
1325
Brian Curtind25aef52011-06-13 15:16:04 -05001326 /* only recheck */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001327 if (-1 == has_GetFinalPathNameByHandle)
Brian Curtind25aef52011-06-13 15:16:04 -05001328 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001329 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001330 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1331 "GetFinalPathNameByHandleA");
1332 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1333 "GetFinalPathNameByHandleW");
1334 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1335 Py_GetFinalPathNameByHandleW;
1336 }
1337 return has_GetFinalPathNameByHandle;
1338}
1339
1340static BOOL
1341get_target_path(HANDLE hdl, wchar_t **target_path)
1342{
1343 int buf_size, result_length;
1344 wchar_t *buf;
1345
1346 /* We have a good handle to the target, use it to determine
1347 the target path name (then we'll call lstat on it). */
1348 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1349 VOLUME_NAME_DOS);
1350 if(!buf_size)
1351 return FALSE;
1352
1353 buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001354 if (!buf) {
1355 SetLastError(ERROR_OUTOFMEMORY);
1356 return FALSE;
1357 }
1358
Brian Curtind25aef52011-06-13 15:16:04 -05001359 result_length = Py_GetFinalPathNameByHandleW(hdl,
1360 buf, buf_size, VOLUME_NAME_DOS);
1361
1362 if(!result_length) {
1363 free(buf);
1364 return FALSE;
1365 }
1366
1367 if(!CloseHandle(hdl)) {
1368 free(buf);
1369 return FALSE;
1370 }
1371
1372 buf[result_length] = 0;
1373
1374 *target_path = buf;
1375 return TRUE;
1376}
1377
1378static int
1379win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1380 BOOL traverse);
1381static int
1382win32_xstat_impl(const char *path, struct win32_stat *result,
1383 BOOL traverse)
1384{
Victor Stinner26de69d2011-06-17 15:15:38 +02001385 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001386 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001387 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001388 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001389 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001390 const char *dot;
1391
Brian Curtind25aef52011-06-13 15:16:04 -05001392 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001393 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1394 traverse reparse point. */
1395 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001396 }
1397
Brian Curtinf5e76d02010-11-24 13:14:05 +00001398 hFile = CreateFileA(
1399 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001400 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001401 0, /* share mode */
1402 NULL, /* security attributes */
1403 OPEN_EXISTING,
1404 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001405 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1406 Because of this, calls like GetFinalPathNameByHandle will return
1407 the symlink path agin and not the actual final path. */
1408 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1409 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001410 NULL);
1411
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001412 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001413 /* Either the target doesn't exist, or we don't have access to
1414 get a handle to it. If the former, we need to return an error.
1415 If the latter, we can use attributes_from_dir. */
1416 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001417 return -1;
1418 /* Could not get attributes on open file. Fall back to
1419 reading the directory. */
1420 if (!attributes_from_dir(path, &info, &reparse_tag))
1421 /* Very strange. This should not fail now */
1422 return -1;
1423 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1424 if (traverse) {
1425 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001426 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001427 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001428 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001429 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001430 } else {
1431 if (!GetFileInformationByHandle(hFile, &info)) {
1432 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001433 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001434 }
1435 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001436 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1437 return -1;
1438
1439 /* Close the outer open file handle now that we're about to
1440 reopen it with different flags. */
1441 if (!CloseHandle(hFile))
1442 return -1;
1443
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001444 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001445 /* In order to call GetFinalPathNameByHandle we need to open
1446 the file without the reparse handling flag set. */
1447 hFile2 = CreateFileA(
1448 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1449 NULL, OPEN_EXISTING,
1450 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1451 NULL);
1452 if (hFile2 == INVALID_HANDLE_VALUE)
1453 return -1;
1454
1455 if (!get_target_path(hFile2, &target_path))
1456 return -1;
1457
1458 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001459 free(target_path);
1460 return code;
1461 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001462 } else
1463 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001464 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001465 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001466
1467 /* Set S_IEXEC if it is an .exe, .bat, ... */
1468 dot = strrchr(path, '.');
1469 if (dot) {
1470 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1471 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1472 result->st_mode |= 0111;
1473 }
1474 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001475}
1476
1477static int
Brian Curtind25aef52011-06-13 15:16:04 -05001478win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1479 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001480{
1481 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001482 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001483 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001484 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001485 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001486 const wchar_t *dot;
1487
Brian Curtind25aef52011-06-13 15:16:04 -05001488 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001489 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1490 traverse reparse point. */
1491 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001492 }
1493
Brian Curtinf5e76d02010-11-24 13:14:05 +00001494 hFile = CreateFileW(
1495 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001496 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001497 0, /* share mode */
1498 NULL, /* security attributes */
1499 OPEN_EXISTING,
1500 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001501 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1502 Because of this, calls like GetFinalPathNameByHandle will return
1503 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001504 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001505 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001506 NULL);
1507
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001508 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001509 /* Either the target doesn't exist, or we don't have access to
1510 get a handle to it. If the former, we need to return an error.
1511 If the latter, we can use attributes_from_dir. */
1512 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001513 return -1;
1514 /* Could not get attributes on open file. Fall back to
1515 reading the directory. */
1516 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1517 /* Very strange. This should not fail now */
1518 return -1;
1519 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1520 if (traverse) {
1521 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001522 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001523 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001524 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001525 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001526 } else {
1527 if (!GetFileInformationByHandle(hFile, &info)) {
1528 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001529 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001530 }
1531 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001532 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1533 return -1;
1534
1535 /* Close the outer open file handle now that we're about to
1536 reopen it with different flags. */
1537 if (!CloseHandle(hFile))
1538 return -1;
1539
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001540 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001541 /* In order to call GetFinalPathNameByHandle we need to open
1542 the file without the reparse handling flag set. */
1543 hFile2 = CreateFileW(
1544 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1545 NULL, OPEN_EXISTING,
1546 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1547 NULL);
1548 if (hFile2 == INVALID_HANDLE_VALUE)
1549 return -1;
1550
1551 if (!get_target_path(hFile2, &target_path))
1552 return -1;
1553
1554 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001555 free(target_path);
1556 return code;
1557 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001558 } else
1559 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001560 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001561 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001562
1563 /* Set S_IEXEC if it is an .exe, .bat, ... */
1564 dot = wcsrchr(path, '.');
1565 if (dot) {
1566 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1567 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1568 result->st_mode |= 0111;
1569 }
1570 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001571}
1572
1573static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001574win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001575{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001576 /* Protocol violation: we explicitly clear errno, instead of
1577 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001578 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001579 errno = 0;
1580 return code;
1581}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001582
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001583static int
1584win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1585{
1586 /* Protocol violation: we explicitly clear errno, instead of
1587 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001588 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001589 errno = 0;
1590 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001591}
Brian Curtind25aef52011-06-13 15:16:04 -05001592/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001593
1594 In Posix, stat automatically traverses symlinks and returns the stat
1595 structure for the target. In Windows, the equivalent GetFileAttributes by
1596 default does not traverse symlinks and instead returns attributes for
1597 the symlink.
1598
1599 Therefore, win32_lstat will get the attributes traditionally, and
1600 win32_stat will first explicitly resolve the symlink target and then will
1601 call win32_lstat on that result.
1602
Ezio Melotti4969f702011-03-15 05:59:46 +02001603 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001604
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001605static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001606win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001607{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001608 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001609}
1610
Victor Stinner8c62be82010-05-06 00:08:46 +00001611static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001612win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001613{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001614 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001615}
1616
1617static int
1618win32_stat(const char* path, struct win32_stat *result)
1619{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001620 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001621}
1622
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001623static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001624win32_stat_w(const wchar_t* path, struct win32_stat *result)
1625{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001626 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001627}
1628
1629static int
1630win32_fstat(int file_number, struct win32_stat *result)
1631{
Victor Stinner8c62be82010-05-06 00:08:46 +00001632 BY_HANDLE_FILE_INFORMATION info;
1633 HANDLE h;
1634 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001635
Richard Oudkerk2240ac12012-07-06 12:05:32 +01001636 if (!_PyVerify_fd(file_number))
1637 h = INVALID_HANDLE_VALUE;
1638 else
1639 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001640
Victor Stinner8c62be82010-05-06 00:08:46 +00001641 /* Protocol violation: we explicitly clear errno, instead of
1642 setting it to a POSIX error. Callers should use GetLastError. */
1643 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001644
Victor Stinner8c62be82010-05-06 00:08:46 +00001645 if (h == INVALID_HANDLE_VALUE) {
1646 /* This is really a C library error (invalid file handle).
1647 We set the Win32 error to the closes one matching. */
1648 SetLastError(ERROR_INVALID_HANDLE);
1649 return -1;
1650 }
1651 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001652
Victor Stinner8c62be82010-05-06 00:08:46 +00001653 type = GetFileType(h);
1654 if (type == FILE_TYPE_UNKNOWN) {
1655 DWORD error = GetLastError();
1656 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001657 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001658 }
1659 /* else: valid but unknown file */
1660 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001661
Victor Stinner8c62be82010-05-06 00:08:46 +00001662 if (type != FILE_TYPE_DISK) {
1663 if (type == FILE_TYPE_CHAR)
1664 result->st_mode = _S_IFCHR;
1665 else if (type == FILE_TYPE_PIPE)
1666 result->st_mode = _S_IFIFO;
1667 return 0;
1668 }
1669
1670 if (!GetFileInformationByHandle(h, &info)) {
1671 return -1;
1672 }
1673
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001674 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001675 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001676 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1677 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001678}
1679
1680#endif /* MS_WINDOWS */
1681
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001682PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001683"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001684This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001685 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001686or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1687\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001688Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1689or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001690\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001691See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001692
1693static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001694 {"st_mode", "protection bits"},
1695 {"st_ino", "inode"},
1696 {"st_dev", "device"},
1697 {"st_nlink", "number of hard links"},
1698 {"st_uid", "user ID of owner"},
1699 {"st_gid", "group ID of owner"},
1700 {"st_size", "total size, in bytes"},
1701 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1702 {NULL, "integer time of last access"},
1703 {NULL, "integer time of last modification"},
1704 {NULL, "integer time of last change"},
1705 {"st_atime", "time of last access"},
1706 {"st_mtime", "time of last modification"},
1707 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001708 {"st_atime_ns", "time of last access in nanoseconds"},
1709 {"st_mtime_ns", "time of last modification in nanoseconds"},
1710 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001711#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001712 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001713#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001714#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001715 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001716#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001717#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001718 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001719#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001720#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001721 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001722#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001723#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001724 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001725#endif
1726#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001727 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001728#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001729 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001730};
1731
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001732#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001733#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001734#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001735#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001736#endif
1737
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001738#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001739#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1740#else
1741#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1742#endif
1743
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001744#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001745#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1746#else
1747#define ST_RDEV_IDX ST_BLOCKS_IDX
1748#endif
1749
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001750#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1751#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1752#else
1753#define ST_FLAGS_IDX ST_RDEV_IDX
1754#endif
1755
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001756#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001757#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001758#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001759#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001760#endif
1761
1762#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1763#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1764#else
1765#define ST_BIRTHTIME_IDX ST_GEN_IDX
1766#endif
1767
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001768static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001769 "stat_result", /* name */
1770 stat_result__doc__, /* doc */
1771 stat_result_fields,
1772 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001773};
1774
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001775PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001776"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1777This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001778 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001779or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001780\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001781See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001782
1783static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001784 {"f_bsize", },
1785 {"f_frsize", },
1786 {"f_blocks", },
1787 {"f_bfree", },
1788 {"f_bavail", },
1789 {"f_files", },
1790 {"f_ffree", },
1791 {"f_favail", },
1792 {"f_flag", },
1793 {"f_namemax",},
1794 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001795};
1796
1797static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001798 "statvfs_result", /* name */
1799 statvfs_result__doc__, /* doc */
1800 statvfs_result_fields,
1801 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001802};
1803
Ross Lagerwall7807c352011-03-17 20:20:30 +02001804#if defined(HAVE_WAITID) && !defined(__APPLE__)
1805PyDoc_STRVAR(waitid_result__doc__,
1806"waitid_result: Result from waitid.\n\n\
1807This object may be accessed either as a tuple of\n\
1808 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1809or via the attributes si_pid, si_uid, and so on.\n\
1810\n\
1811See os.waitid for more information.");
1812
1813static PyStructSequence_Field waitid_result_fields[] = {
1814 {"si_pid", },
1815 {"si_uid", },
1816 {"si_signo", },
1817 {"si_status", },
1818 {"si_code", },
1819 {0}
1820};
1821
1822static PyStructSequence_Desc waitid_result_desc = {
1823 "waitid_result", /* name */
1824 waitid_result__doc__, /* doc */
1825 waitid_result_fields,
1826 5
1827};
1828static PyTypeObject WaitidResultType;
1829#endif
1830
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001831static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001832static PyTypeObject StatResultType;
1833static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001834#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001835static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001836#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001837static newfunc structseq_new;
1838
1839static PyObject *
1840statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1841{
Victor Stinner8c62be82010-05-06 00:08:46 +00001842 PyStructSequence *result;
1843 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001844
Victor Stinner8c62be82010-05-06 00:08:46 +00001845 result = (PyStructSequence*)structseq_new(type, args, kwds);
1846 if (!result)
1847 return NULL;
1848 /* If we have been initialized from a tuple,
1849 st_?time might be set to None. Initialize it
1850 from the int slots. */
1851 for (i = 7; i <= 9; i++) {
1852 if (result->ob_item[i+3] == Py_None) {
1853 Py_DECREF(Py_None);
1854 Py_INCREF(result->ob_item[i]);
1855 result->ob_item[i+3] = result->ob_item[i];
1856 }
1857 }
1858 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001859}
1860
1861
1862
1863/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001864static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001865
1866PyDoc_STRVAR(stat_float_times__doc__,
1867"stat_float_times([newval]) -> oldval\n\n\
1868Determine whether os.[lf]stat represents time stamps as float objects.\n\
1869If newval is True, future calls to stat() return floats, if it is False,\n\
1870future calls return ints. \n\
1871If newval is omitted, return the current setting.\n");
1872
1873static PyObject*
1874stat_float_times(PyObject* self, PyObject *args)
1875{
Victor Stinner8c62be82010-05-06 00:08:46 +00001876 int newval = -1;
1877 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1878 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001879 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1880 "stat_float_times() is deprecated",
1881 1))
1882 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001883 if (newval == -1)
1884 /* Return old value */
1885 return PyBool_FromLong(_stat_float_times);
1886 _stat_float_times = newval;
1887 Py_INCREF(Py_None);
1888 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001889}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001890
Larry Hastings6fe20b32012-04-19 15:07:49 -07001891static PyObject *billion = NULL;
1892
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001893static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001894fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001895{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001896 PyObject *s = _PyLong_FromTime_t(sec);
1897 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1898 PyObject *s_in_ns = NULL;
1899 PyObject *ns_total = NULL;
1900 PyObject *float_s = NULL;
1901
1902 if (!(s && ns_fractional))
1903 goto exit;
1904
1905 s_in_ns = PyNumber_Multiply(s, billion);
1906 if (!s_in_ns)
1907 goto exit;
1908
1909 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1910 if (!ns_total)
1911 goto exit;
1912
Victor Stinner4195b5c2012-02-08 23:03:19 +01001913 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001914 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1915 if (!float_s)
1916 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001917 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001918 else {
1919 float_s = s;
1920 Py_INCREF(float_s);
1921 }
1922
1923 PyStructSequence_SET_ITEM(v, index, s);
1924 PyStructSequence_SET_ITEM(v, index+3, float_s);
1925 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1926 s = NULL;
1927 float_s = NULL;
1928 ns_total = NULL;
1929exit:
1930 Py_XDECREF(s);
1931 Py_XDECREF(ns_fractional);
1932 Py_XDECREF(s_in_ns);
1933 Py_XDECREF(ns_total);
1934 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001935}
1936
Tim Peters5aa91602002-01-30 05:46:57 +00001937/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001938 (used by posix_stat() and posix_fstat()) */
1939static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001940_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001941{
Victor Stinner8c62be82010-05-06 00:08:46 +00001942 unsigned long ansec, mnsec, cnsec;
1943 PyObject *v = PyStructSequence_New(&StatResultType);
1944 if (v == NULL)
1945 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001946
Victor Stinner8c62be82010-05-06 00:08:46 +00001947 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001948#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001949 PyStructSequence_SET_ITEM(v, 1,
1950 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001951#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001952 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001953#endif
1954#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001955 PyStructSequence_SET_ITEM(v, 2,
1956 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001957#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001958 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001959#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001960 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1961 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1962 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001963#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001964 PyStructSequence_SET_ITEM(v, 6,
1965 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001966#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001967 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001968#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001969
Martin v. Löwis14694662006-02-03 12:54:16 +00001970#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001971 ansec = st->st_atim.tv_nsec;
1972 mnsec = st->st_mtim.tv_nsec;
1973 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001974#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001975 ansec = st->st_atimespec.tv_nsec;
1976 mnsec = st->st_mtimespec.tv_nsec;
1977 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001978#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001979 ansec = st->st_atime_nsec;
1980 mnsec = st->st_mtime_nsec;
1981 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001982#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001983 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001984#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01001985 fill_time(v, 7, st->st_atime, ansec);
1986 fill_time(v, 8, st->st_mtime, mnsec);
1987 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001988
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001989#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001990 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1991 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001992#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001993#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001994 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1995 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001996#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001997#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001998 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1999 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002000#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002001#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002002 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2003 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002004#endif
2005#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002006 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002007 PyObject *val;
2008 unsigned long bsec,bnsec;
2009 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002010#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002011 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002012#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002013 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002014#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002015 if (_stat_float_times) {
2016 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2017 } else {
2018 val = PyLong_FromLong((long)bsec);
2019 }
2020 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2021 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002022 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002023#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002024#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002025 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2026 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002027#endif
Fred Drake699f3522000-06-29 21:12:41 +00002028
Victor Stinner8c62be82010-05-06 00:08:46 +00002029 if (PyErr_Occurred()) {
2030 Py_DECREF(v);
2031 return NULL;
2032 }
Fred Drake699f3522000-06-29 21:12:41 +00002033
Victor Stinner8c62be82010-05-06 00:08:46 +00002034 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002035}
2036
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002037/* POSIX methods */
2038
Guido van Rossum94f6f721999-01-06 18:42:14 +00002039
2040static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002041posix_do_stat(char *function_name, path_t *path,
2042 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002043{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002044 STRUCT_STAT st;
2045 int result;
2046
2047#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2048 if (follow_symlinks_specified(function_name, follow_symlinks))
2049 return NULL;
2050#endif
2051
2052 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2053 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2054 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2055 return NULL;
2056
2057 Py_BEGIN_ALLOW_THREADS
2058 if (path->fd != -1)
2059 result = FSTAT(path->fd, &st);
2060 else
2061#ifdef MS_WINDOWS
2062 if (path->wide) {
2063 if (follow_symlinks)
2064 result = win32_stat_w(path->wide, &st);
2065 else
2066 result = win32_lstat_w(path->wide, &st);
2067 }
2068 else
2069#endif
2070#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2071 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2072 result = LSTAT(path->narrow, &st);
2073 else
2074#endif
2075#ifdef HAVE_FSTATAT
2076 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2077 result = fstatat(dir_fd, path->narrow, &st,
2078 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2079 else
2080#endif
2081 result = STAT(path->narrow, &st);
2082 Py_END_ALLOW_THREADS
2083
Victor Stinner292c8352012-10-30 02:17:38 +01002084 if (result != 0) {
2085 return path_error(path);
2086 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002087
2088 return _pystat_fromstructstat(&st);
2089}
2090
2091PyDoc_STRVAR(posix_stat__doc__,
2092"stat(path, *, dir_fd=None, follow_symlinks=True) -> stat result\n\n\
2093Perform a stat system call on the given path.\n\
2094\n\
2095path may be specified as either a string or as an open file descriptor.\n\
2096\n\
2097If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2098 and path should be relative; path will then be relative to that directory.\n\
2099 dir_fd may not be supported on your platform; if it is unavailable, using\n\
2100 it will raise a NotImplementedError.\n\
2101If follow_symlinks is False, and the last element of the path is a symbolic\n\
2102 link, stat will examine the symbolic link itself instead of the file the\n\
2103 link points to.\n\
2104It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2105 an open file descriptor.");
2106
2107static PyObject *
2108posix_stat(PyObject *self, PyObject *args, PyObject *kwargs)
2109{
2110 static char *keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2111 path_t path;
2112 int dir_fd = DEFAULT_DIR_FD;
2113 int follow_symlinks = 1;
2114 PyObject *return_value;
2115
2116 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002117 path.function_name = "stat";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002118 path.allow_fd = 1;
2119 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:stat", keywords,
2120 path_converter, &path,
2121#ifdef HAVE_FSTATAT
2122 dir_fd_converter, &dir_fd,
2123#else
2124 dir_fd_unavailable, &dir_fd,
2125#endif
2126 &follow_symlinks))
2127 return NULL;
2128 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2129 path_cleanup(&path);
2130 return return_value;
2131}
2132
2133PyDoc_STRVAR(posix_lstat__doc__,
2134"lstat(path, *, dir_fd=None) -> stat result\n\n\
2135Like stat(), but do not follow symbolic links.\n\
2136Equivalent to stat(path, follow_symlinks=False).");
2137
2138static PyObject *
2139posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2140{
2141 static char *keywords[] = {"path", "dir_fd", NULL};
2142 path_t path;
2143 int dir_fd = DEFAULT_DIR_FD;
2144 int follow_symlinks = 0;
2145 PyObject *return_value;
2146
2147 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002148 path.function_name = "lstat";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002149 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2150 path_converter, &path,
2151#ifdef HAVE_FSTATAT
2152 dir_fd_converter, &dir_fd
2153#else
2154 dir_fd_unavailable, &dir_fd
2155#endif
2156 ))
2157 return NULL;
2158 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2159 path_cleanup(&path);
2160 return return_value;
2161}
2162
2163PyDoc_STRVAR(posix_access__doc__,
2164"access(path, mode, *, dir_fd=None, effective_ids=False,\
2165 follow_symlinks=True)\n\n\
2166Use the real uid/gid to test for access to a path. Returns True if granted,\n\
2167False otherwise.\n\
2168\n\
2169If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2170 and path should be relative; path will then be relative to that directory.\n\
2171If effective_ids is True, access will use the effective uid/gid instead of\n\
2172 the real uid/gid.\n\
2173If follow_symlinks is False, and the last element of the path is a symbolic\n\
2174 link, access will examine the symbolic link itself instead of the file the\n\
2175 link points to.\n\
2176dir_fd, effective_ids, and follow_symlinks may not be implemented\n\
2177 on your platform. If they are unavailable, using them will raise a\n\
2178 NotImplementedError.\n\
2179\n\
2180Note that most operations will use the effective uid/gid, therefore this\n\
2181 routine can be used in a suid/sgid environment to test if the invoking user\n\
2182 has the specified access to the path.\n\
2183The mode argument can be F_OK to test existence, or the inclusive-OR\n\
2184 of R_OK, W_OK, and X_OK.");
2185
2186static PyObject *
2187posix_access(PyObject *self, PyObject *args, PyObject *kwargs)
2188{
2189 static char *keywords[] = {"path", "mode", "dir_fd", "effective_ids",
2190 "follow_symlinks", NULL};
2191 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002192 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002193 int dir_fd = DEFAULT_DIR_FD;
2194 int effective_ids = 0;
2195 int follow_symlinks = 1;
2196 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002197
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002198#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002199 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002200#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002201 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002202#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002203
2204 memset(&path, 0, sizeof(path));
2205 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&pp:access", keywords,
2206 path_converter, &path, &mode,
2207#ifdef HAVE_FACCESSAT
2208 dir_fd_converter, &dir_fd,
2209#else
2210 dir_fd_unavailable, &dir_fd,
2211#endif
2212 &effective_ids, &follow_symlinks))
2213 return NULL;
2214
2215#ifndef HAVE_FACCESSAT
2216 if (follow_symlinks_specified("access", follow_symlinks))
2217 goto exit;
2218
2219 if (effective_ids) {
2220 argument_unavailable_error("access", "effective_ids");
2221 goto exit;
2222 }
2223#endif
2224
2225#ifdef MS_WINDOWS
2226 Py_BEGIN_ALLOW_THREADS
2227 if (path.wide != NULL)
2228 attr = GetFileAttributesW(path.wide);
2229 else
2230 attr = GetFileAttributesA(path.narrow);
2231 Py_END_ALLOW_THREADS
2232
2233 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002234 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002235 * * we didn't get a -1, and
2236 * * write access wasn't requested,
2237 * * or the file isn't read-only,
2238 * * or it's a directory.
2239 * (Directories cannot be read-only on Windows.)
2240 */
2241 return_value = PyBool_FromLong(
2242 (attr != 0xFFFFFFFF) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002243 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002244 !(attr & FILE_ATTRIBUTE_READONLY) ||
2245 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2246#else
2247
2248 Py_BEGIN_ALLOW_THREADS
2249#ifdef HAVE_FACCESSAT
2250 if ((dir_fd != DEFAULT_DIR_FD) ||
2251 effective_ids ||
2252 !follow_symlinks) {
2253 int flags = 0;
2254 if (!follow_symlinks)
2255 flags |= AT_SYMLINK_NOFOLLOW;
2256 if (effective_ids)
2257 flags |= AT_EACCESS;
2258 result = faccessat(dir_fd, path.narrow, mode, flags);
2259 }
2260 else
2261#endif
2262 result = access(path.narrow, mode);
2263 Py_END_ALLOW_THREADS
2264 return_value = PyBool_FromLong(!result);
2265#endif
2266
2267#ifndef HAVE_FACCESSAT
2268exit:
2269#endif
2270 path_cleanup(&path);
2271 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002272}
2273
Guido van Rossumd371ff11999-01-25 16:12:23 +00002274#ifndef F_OK
2275#define F_OK 0
2276#endif
2277#ifndef R_OK
2278#define R_OK 4
2279#endif
2280#ifndef W_OK
2281#define W_OK 2
2282#endif
2283#ifndef X_OK
2284#define X_OK 1
2285#endif
2286
2287#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002288PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002289"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002290Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00002291
2292static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002293posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002294{
Victor Stinner8c62be82010-05-06 00:08:46 +00002295 int id;
2296 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002297
Victor Stinner8c62be82010-05-06 00:08:46 +00002298 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
2299 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002300
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002301#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002302 /* file descriptor 0 only, the default input device (stdin) */
2303 if (id == 0) {
2304 ret = ttyname();
2305 }
2306 else {
2307 ret = NULL;
2308 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002309#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002310 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002311#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002312 if (ret == NULL)
2313 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002314 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002315}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002316#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002317
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002318#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002319PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002320"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002321Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002322
2323static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002324posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002325{
Victor Stinner8c62be82010-05-06 00:08:46 +00002326 char *ret;
2327 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002328
Greg Wardb48bc172000-03-01 21:51:56 +00002329#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002330 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002331#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002332 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002333#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002334 if (ret == NULL)
2335 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002336 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002337}
2338#endif
2339
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002340PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002341"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002342Change the current working directory to the specified path.\n\
2343\n\
2344path may always be specified as a string.\n\
2345On some platforms, path may also be specified as an open file descriptor.\n\
2346 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002347
Barry Warsaw53699e91996-12-10 23:23:01 +00002348static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002349posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002350{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002351 path_t path;
2352 int result;
2353 PyObject *return_value = NULL;
2354 static char *keywords[] = {"path", NULL};
2355
2356 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002357 path.function_name = "chdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002358#ifdef HAVE_FCHDIR
2359 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002360#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002361 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2362 path_converter, &path
2363 ))
2364 return NULL;
2365
2366 Py_BEGIN_ALLOW_THREADS
2367#ifdef MS_WINDOWS
2368 if (path.wide)
2369 result = win32_wchdir(path.wide);
2370 else
2371 result = win32_chdir(path.narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002372 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002373#else
2374#ifdef HAVE_FCHDIR
2375 if (path.fd != -1)
2376 result = fchdir(path.fd);
2377 else
2378#endif
2379 result = chdir(path.narrow);
2380#endif
2381 Py_END_ALLOW_THREADS
2382
2383 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002384 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002385 goto exit;
2386 }
2387
2388 return_value = Py_None;
2389 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02002390
Larry Hastings9cf065c2012-06-22 16:30:09 -07002391exit:
2392 path_cleanup(&path);
2393 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002394}
2395
Fred Drake4d1e64b2002-04-15 19:40:07 +00002396#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002397PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002398"fchdir(fd)\n\n\
2399Change to the directory of the given file descriptor. fd must be\n\
2400opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002401
2402static PyObject *
2403posix_fchdir(PyObject *self, PyObject *fdobj)
2404{
Victor Stinner8c62be82010-05-06 00:08:46 +00002405 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002406}
2407#endif /* HAVE_FCHDIR */
2408
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002409
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002410PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002411"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2412Change the access permissions of a file.\n\
2413\n\
2414path may always be specified as a string.\n\
2415On some platforms, path may also be specified as an open file descriptor.\n\
2416 If this functionality is unavailable, using it raises an exception.\n\
2417If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2418 and path should be relative; path will then be relative to that directory.\n\
2419If follow_symlinks is False, and the last element of the path is a symbolic\n\
2420 link, chmod will modify the symbolic link itself instead of the file the\n\
2421 link points to.\n\
2422It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2423 an open file descriptor.\n\
2424dir_fd and follow_symlinks may not be implemented on your platform.\n\
2425 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002426
Barry Warsaw53699e91996-12-10 23:23:01 +00002427static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002428posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002429{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002430 path_t path;
2431 int mode;
2432 int dir_fd = DEFAULT_DIR_FD;
2433 int follow_symlinks = 1;
2434 int result;
2435 PyObject *return_value = NULL;
2436 static char *keywords[] = {"path", "mode", "dir_fd",
2437 "follow_symlinks", NULL};
2438
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002439#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002440 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002441#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002442
Larry Hastings9cf065c2012-06-22 16:30:09 -07002443#ifdef HAVE_FCHMODAT
2444 int fchmodat_nofollow_unsupported = 0;
2445#endif
2446
2447 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002448 path.function_name = "chmod";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002449#ifdef HAVE_FCHMOD
2450 path.allow_fd = 1;
2451#endif
2452 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2453 path_converter, &path,
2454 &mode,
2455#ifdef HAVE_FCHMODAT
2456 dir_fd_converter, &dir_fd,
2457#else
2458 dir_fd_unavailable, &dir_fd,
2459#endif
2460 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002461 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002462
2463#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2464 if (follow_symlinks_specified("chmod", follow_symlinks))
2465 goto exit;
2466#endif
2467
2468#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002469 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002470 if (path.wide)
2471 attr = GetFileAttributesW(path.wide);
2472 else
2473 attr = GetFileAttributesA(path.narrow);
2474 if (attr == 0xFFFFFFFF)
2475 result = 0;
2476 else {
2477 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002478 attr &= ~FILE_ATTRIBUTE_READONLY;
2479 else
2480 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002481 if (path.wide)
2482 result = SetFileAttributesW(path.wide, attr);
2483 else
2484 result = SetFileAttributesA(path.narrow, attr);
2485 }
2486 Py_END_ALLOW_THREADS
2487
2488 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01002489 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002490 goto exit;
2491 }
2492#else /* MS_WINDOWS */
2493 Py_BEGIN_ALLOW_THREADS
2494#ifdef HAVE_FCHMOD
2495 if (path.fd != -1)
2496 result = fchmod(path.fd, mode);
2497 else
2498#endif
2499#ifdef HAVE_LCHMOD
2500 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2501 result = lchmod(path.narrow, mode);
2502 else
2503#endif
2504#ifdef HAVE_FCHMODAT
2505 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2506 /*
2507 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2508 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002509 * and then says it isn't implemented yet.
2510 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002511 *
2512 * Once it is supported, os.chmod will automatically
2513 * support dir_fd and follow_symlinks=False. (Hopefully.)
2514 * Until then, we need to be careful what exception we raise.
2515 */
2516 result = fchmodat(dir_fd, path.narrow, mode,
2517 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2518 /*
2519 * But wait! We can't throw the exception without allowing threads,
2520 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2521 */
2522 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002523 result &&
2524 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2525 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002526 }
2527 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002528#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002529 result = chmod(path.narrow, mode);
2530 Py_END_ALLOW_THREADS
2531
2532 if (result) {
2533#ifdef HAVE_FCHMODAT
2534 if (fchmodat_nofollow_unsupported) {
2535 if (dir_fd != DEFAULT_DIR_FD)
2536 dir_fd_and_follow_symlinks_invalid("chmod",
2537 dir_fd, follow_symlinks);
2538 else
2539 follow_symlinks_specified("chmod", follow_symlinks);
2540 }
2541 else
2542#endif
Victor Stinner292c8352012-10-30 02:17:38 +01002543 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002544 goto exit;
2545 }
2546#endif
2547
2548 Py_INCREF(Py_None);
2549 return_value = Py_None;
2550exit:
2551 path_cleanup(&path);
2552 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002553}
2554
Larry Hastings9cf065c2012-06-22 16:30:09 -07002555
Christian Heimes4e30a842007-11-30 22:12:06 +00002556#ifdef HAVE_FCHMOD
2557PyDoc_STRVAR(posix_fchmod__doc__,
2558"fchmod(fd, mode)\n\n\
2559Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002560descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002561
2562static PyObject *
2563posix_fchmod(PyObject *self, PyObject *args)
2564{
Victor Stinner8c62be82010-05-06 00:08:46 +00002565 int fd, mode, res;
2566 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2567 return NULL;
2568 Py_BEGIN_ALLOW_THREADS
2569 res = fchmod(fd, mode);
2570 Py_END_ALLOW_THREADS
2571 if (res < 0)
2572 return posix_error();
2573 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002574}
2575#endif /* HAVE_FCHMOD */
2576
2577#ifdef HAVE_LCHMOD
2578PyDoc_STRVAR(posix_lchmod__doc__,
2579"lchmod(path, mode)\n\n\
2580Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002581affects the link itself rather than the target.\n\
2582Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002583
2584static PyObject *
2585posix_lchmod(PyObject *self, PyObject *args)
2586{
Victor Stinner292c8352012-10-30 02:17:38 +01002587 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002588 int i;
2589 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01002590 memset(&path, 0, sizeof(path));
2591 path.function_name = "lchmod";
2592 if (!PyArg_ParseTuple(args, "O&i:lchmod",
2593 path_converter, &path, &i))
Victor Stinner8c62be82010-05-06 00:08:46 +00002594 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002595 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002596 res = lchmod(path.narrow, i);
Victor Stinner8c62be82010-05-06 00:08:46 +00002597 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002598 if (res < 0) {
2599 path_error(&path);
2600 path_cleanup(&path);
2601 return NULL;
2602 }
2603 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00002604 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002605}
2606#endif /* HAVE_LCHMOD */
2607
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002608
Thomas Wouterscf297e42007-02-23 15:07:44 +00002609#ifdef HAVE_CHFLAGS
2610PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002611"chflags(path, flags, *, follow_symlinks=True)\n\n\
2612Set file flags.\n\
2613\n\
2614If follow_symlinks is False, and the last element of the path is a symbolic\n\
2615 link, chflags will change flags on the symbolic link itself instead of the\n\
2616 file the link points to.\n\
2617follow_symlinks may not be implemented on your platform. If it is\n\
2618unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002619
2620static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002621posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00002622{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002623 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002624 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002625 int follow_symlinks = 1;
2626 int result;
2627 PyObject *return_value;
2628 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
2629
2630 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002631 path.function_name = "chflags";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002632 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
2633 path_converter, &path,
2634 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002635 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002636
2637#ifndef HAVE_LCHFLAGS
2638 if (follow_symlinks_specified("chflags", follow_symlinks))
2639 goto exit;
2640#endif
2641
Victor Stinner8c62be82010-05-06 00:08:46 +00002642 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002643#ifdef HAVE_LCHFLAGS
2644 if (!follow_symlinks)
2645 result = lchflags(path.narrow, flags);
2646 else
2647#endif
2648 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002649 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002650
2651 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002652 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002653 goto exit;
2654 }
2655
2656 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00002657 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002658
2659exit:
2660 path_cleanup(&path);
2661 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002662}
2663#endif /* HAVE_CHFLAGS */
2664
2665#ifdef HAVE_LCHFLAGS
2666PyDoc_STRVAR(posix_lchflags__doc__,
2667"lchflags(path, flags)\n\n\
2668Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002669This function will not follow symbolic links.\n\
2670Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002671
2672static PyObject *
2673posix_lchflags(PyObject *self, PyObject *args)
2674{
Victor Stinner292c8352012-10-30 02:17:38 +01002675 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002676 unsigned long flags;
2677 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01002678 memset(&path, 0, sizeof(path));
2679 path.function_name = "lchflags";
Victor Stinner8c62be82010-05-06 00:08:46 +00002680 if (!PyArg_ParseTuple(args, "O&k:lchflags",
Victor Stinner292c8352012-10-30 02:17:38 +01002681 path_converter, &path, &flags))
Victor Stinner8c62be82010-05-06 00:08:46 +00002682 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002683 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002684 res = lchflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002685 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002686 if (res < 0) {
2687 path_error(&path);
2688 path_cleanup(&path);
2689 return NULL;
2690 }
2691 path_cleanup(&path);
2692 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002693}
2694#endif /* HAVE_LCHFLAGS */
2695
Martin v. Löwis244edc82001-10-04 22:44:26 +00002696#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002697PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002698"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002699Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002700
2701static PyObject *
2702posix_chroot(PyObject *self, PyObject *args)
2703{
Victor Stinner292c8352012-10-30 02:17:38 +01002704 return posix_1str("chroot", args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002705}
2706#endif
2707
Guido van Rossum21142a01999-01-08 21:05:37 +00002708#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002709PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002710"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002711force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002712
2713static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002714posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002715{
Stefan Krah0e803b32010-11-26 16:16:47 +00002716 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002717}
2718#endif /* HAVE_FSYNC */
2719
Ross Lagerwall7807c352011-03-17 20:20:30 +02002720#ifdef HAVE_SYNC
2721PyDoc_STRVAR(posix_sync__doc__,
2722"sync()\n\n\
2723Force write of everything to disk.");
2724
2725static PyObject *
2726posix_sync(PyObject *self, PyObject *noargs)
2727{
2728 Py_BEGIN_ALLOW_THREADS
2729 sync();
2730 Py_END_ALLOW_THREADS
2731 Py_RETURN_NONE;
2732}
2733#endif
2734
Guido van Rossum21142a01999-01-08 21:05:37 +00002735#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002736
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002737#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002738extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2739#endif
2740
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002741PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002742"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002743force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002744 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002745
2746static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002747posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002748{
Stefan Krah0e803b32010-11-26 16:16:47 +00002749 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002750}
2751#endif /* HAVE_FDATASYNC */
2752
2753
Fredrik Lundh10723342000-07-10 16:38:09 +00002754#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002755PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002756"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
2757Change the owner and group id of path to the numeric uid and gid.\n\
2758\n\
2759path may always be specified as a string.\n\
2760On some platforms, path may also be specified as an open file descriptor.\n\
2761 If this functionality is unavailable, using it raises an exception.\n\
2762If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2763 and path should be relative; path will then be relative to that directory.\n\
2764If follow_symlinks is False, and the last element of the path is a symbolic\n\
2765 link, chown will modify the symbolic link itself instead of the file the\n\
2766 link points to.\n\
2767It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2768 an open file descriptor.\n\
2769dir_fd and follow_symlinks may not be implemented on your platform.\n\
2770 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002771
Barry Warsaw53699e91996-12-10 23:23:01 +00002772static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002773posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002774{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002775 path_t path;
2776 long uid_l, gid_l;
2777 uid_t uid;
2778 gid_t gid;
2779 int dir_fd = DEFAULT_DIR_FD;
2780 int follow_symlinks = 1;
2781 int result;
2782 PyObject *return_value = NULL;
2783 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
2784 "follow_symlinks", NULL};
2785
2786 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002787 path.function_name = "chown";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002788#ifdef HAVE_FCHOWN
2789 path.allow_fd = 1;
2790#endif
2791 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&ll|$O&p:chown", keywords,
2792 path_converter, &path,
2793 &uid_l, &gid_l,
2794#ifdef HAVE_FCHOWNAT
2795 dir_fd_converter, &dir_fd,
2796#else
2797 dir_fd_unavailable, &dir_fd,
2798#endif
2799 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002800 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002801
2802#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
2803 if (follow_symlinks_specified("chown", follow_symlinks))
2804 goto exit;
2805#endif
2806 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
2807 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
2808 goto exit;
2809
2810#ifdef __APPLE__
2811 /*
2812 * This is for Mac OS X 10.3, which doesn't have lchown.
2813 * (But we still have an lchown symbol because of weak-linking.)
2814 * It doesn't have fchownat either. So there's no possibility
2815 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02002816 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002817 if ((!follow_symlinks) && (lchown == NULL)) {
2818 follow_symlinks_specified("chown", follow_symlinks);
2819 goto exit;
2820 }
2821#endif
2822
Victor Stinner8c62be82010-05-06 00:08:46 +00002823 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002824 uid = (uid_t)uid_l;
2825 gid = (uid_t)gid_l;
2826#ifdef HAVE_FCHOWN
2827 if (path.fd != -1)
2828 result = fchown(path.fd, uid, gid);
2829 else
2830#endif
2831#ifdef HAVE_LCHOWN
2832 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2833 result = lchown(path.narrow, uid, gid);
2834 else
2835#endif
2836#ifdef HAVE_FCHOWNAT
2837 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
2838 result = fchownat(dir_fd, path.narrow, uid, gid,
2839 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2840 else
2841#endif
2842 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00002843 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002844
2845 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002846 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002847 goto exit;
2848 }
2849
2850 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00002851 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002852
2853exit:
2854 path_cleanup(&path);
2855 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002856}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002857#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002858
Christian Heimes4e30a842007-11-30 22:12:06 +00002859#ifdef HAVE_FCHOWN
2860PyDoc_STRVAR(posix_fchown__doc__,
2861"fchown(fd, uid, gid)\n\n\
2862Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002863fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002864
2865static PyObject *
2866posix_fchown(PyObject *self, PyObject *args)
2867{
Victor Stinner8c62be82010-05-06 00:08:46 +00002868 int fd;
2869 long uid, gid;
2870 int res;
Victor Stinner26de69d2011-06-17 15:15:38 +02002871 if (!PyArg_ParseTuple(args, "ill:fchown", &fd, &uid, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00002872 return NULL;
2873 Py_BEGIN_ALLOW_THREADS
2874 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2875 Py_END_ALLOW_THREADS
2876 if (res < 0)
2877 return posix_error();
2878 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002879}
2880#endif /* HAVE_FCHOWN */
2881
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002882#ifdef HAVE_LCHOWN
2883PyDoc_STRVAR(posix_lchown__doc__,
2884"lchown(path, uid, gid)\n\n\
2885Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002886This function will not follow symbolic links.\n\
2887Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002888
2889static PyObject *
2890posix_lchown(PyObject *self, PyObject *args)
2891{
Victor Stinner292c8352012-10-30 02:17:38 +01002892 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002893 long uid, gid;
2894 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01002895 memset(&path, 0, sizeof(path));
2896 path.function_name = "lchown";
Victor Stinner8c62be82010-05-06 00:08:46 +00002897 if (!PyArg_ParseTuple(args, "O&ll:lchown",
Victor Stinner292c8352012-10-30 02:17:38 +01002898 path_converter, &path,
Victor Stinner8c62be82010-05-06 00:08:46 +00002899 &uid, &gid))
2900 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002901 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002902 res = lchown(path.narrow, (uid_t) uid, (gid_t) gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00002903 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002904 if (res < 0) {
2905 path_error(&path);
2906 path_cleanup(&path);
2907 return NULL;
2908 }
2909 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00002910 Py_INCREF(Py_None);
2911 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002912}
2913#endif /* HAVE_LCHOWN */
2914
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002915
Guido van Rossum36bc6801995-06-14 22:54:23 +00002916#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002917static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002918posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002919{
Victor Stinner8c62be82010-05-06 00:08:46 +00002920 char buf[1026];
2921 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002922
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002923#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002924 if (!use_bytes) {
2925 wchar_t wbuf[1026];
2926 wchar_t *wbuf2 = wbuf;
2927 PyObject *resobj;
2928 DWORD len;
2929 Py_BEGIN_ALLOW_THREADS
2930 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2931 /* If the buffer is large enough, len does not include the
2932 terminating \0. If the buffer is too small, len includes
2933 the space needed for the terminator. */
2934 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2935 wbuf2 = malloc(len * sizeof(wchar_t));
2936 if (wbuf2)
2937 len = GetCurrentDirectoryW(len, wbuf2);
2938 }
2939 Py_END_ALLOW_THREADS
2940 if (!wbuf2) {
2941 PyErr_NoMemory();
2942 return NULL;
2943 }
2944 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01002945 if (wbuf2 != wbuf)
2946 free(wbuf2);
2947 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00002948 }
2949 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01002950 if (wbuf2 != wbuf)
2951 free(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00002952 return resobj;
2953 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01002954
2955 if (win32_warn_bytes_api())
2956 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002957#endif
2958
Victor Stinner8c62be82010-05-06 00:08:46 +00002959 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002960 res = getcwd(buf, sizeof buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00002961 Py_END_ALLOW_THREADS
2962 if (res == NULL)
2963 return posix_error();
2964 if (use_bytes)
2965 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00002966 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002967}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002968
2969PyDoc_STRVAR(posix_getcwd__doc__,
2970"getcwd() -> path\n\n\
2971Return a unicode string representing the current working directory.");
2972
2973static PyObject *
2974posix_getcwd_unicode(PyObject *self)
2975{
2976 return posix_getcwd(0);
2977}
2978
2979PyDoc_STRVAR(posix_getcwdb__doc__,
2980"getcwdb() -> path\n\n\
2981Return a bytes string representing the current working directory.");
2982
2983static PyObject *
2984posix_getcwd_bytes(PyObject *self)
2985{
2986 return posix_getcwd(1);
2987}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002988#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002989
Larry Hastings9cf065c2012-06-22 16:30:09 -07002990#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
2991#define HAVE_LINK 1
2992#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002993
Guido van Rossumb6775db1994-08-01 11:34:53 +00002994#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002995PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002996"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
2997Create a hard link to a file.\n\
2998\n\
2999If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3000 descriptor open to a directory, and the respective path string (src or dst)\n\
3001 should be relative; the path will then be relative to that directory.\n\
3002If follow_symlinks is False, and the last element of src is a symbolic\n\
3003 link, link will create a link to the symbolic link itself instead of the\n\
3004 file the link points to.\n\
3005src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3006 platform. If they are unavailable, using them will raise a\n\
3007 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003008
Barry Warsaw53699e91996-12-10 23:23:01 +00003009static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003010posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003011{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003012 path_t src, dst;
3013 int src_dir_fd = DEFAULT_DIR_FD;
3014 int dst_dir_fd = DEFAULT_DIR_FD;
3015 int follow_symlinks = 1;
3016 PyObject *return_value = NULL;
3017 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3018 "follow_symlinks", NULL};
3019#ifdef MS_WINDOWS
3020 BOOL result;
3021#else
3022 int result;
3023#endif
3024
3025 memset(&src, 0, sizeof(src));
3026 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01003027 src.function_name = "link";
3028 dst.function_name = "link";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003029 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3030 path_converter, &src,
3031 path_converter, &dst,
3032 dir_fd_converter, &src_dir_fd,
3033 dir_fd_converter, &dst_dir_fd,
3034 &follow_symlinks))
3035 return NULL;
3036
3037#ifndef HAVE_LINKAT
3038 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3039 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3040 goto exit;
3041 }
3042#endif
3043
3044 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3045 PyErr_SetString(PyExc_NotImplementedError,
3046 "link: src and dst must be the same type");
3047 goto exit;
3048 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003049
Brian Curtin1b9df392010-11-24 20:24:31 +00003050#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003051 Py_BEGIN_ALLOW_THREADS
3052 if (src.wide)
3053 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3054 else
3055 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3056 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003057
Larry Hastings9cf065c2012-06-22 16:30:09 -07003058 if (!result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01003059 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003060 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003061 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003062#else
3063 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003064#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003065 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3066 (dst_dir_fd != DEFAULT_DIR_FD) ||
3067 (!follow_symlinks))
3068 result = linkat(src_dir_fd, src.narrow,
3069 dst_dir_fd, dst.narrow,
3070 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3071 else
3072#endif
3073 result = link(src.narrow, dst.narrow);
3074 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003075
Larry Hastings9cf065c2012-06-22 16:30:09 -07003076 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003077 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003078 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003079 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003080#endif
3081
3082 return_value = Py_None;
3083 Py_INCREF(Py_None);
3084
3085exit:
3086 path_cleanup(&src);
3087 path_cleanup(&dst);
3088 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003089}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003090#endif
3091
Brian Curtin1b9df392010-11-24 20:24:31 +00003092
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003093
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003094PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastingsfdaea062012-06-25 04:42:23 -07003095"listdir(path='.') -> list_of_filenames\n\n\
3096Return a list containing the names of the files in the directory.\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003097The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003098entries '.' and '..' even if they are present in the directory.\n\
3099\n\
Larry Hastingsfdaea062012-06-25 04:42:23 -07003100path can be specified as either str or bytes. If path is bytes,\n\
3101 the filenames returned will also be bytes; in all other circumstances\n\
3102 the filenames returned will be str.\n\
3103On some platforms, path may also be specified as an open file descriptor;\n\
3104 the file descriptor must refer to a directory.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003105 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003106
Barry Warsaw53699e91996-12-10 23:23:01 +00003107static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003108posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003109{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003110 path_t path;
3111 PyObject *list = NULL;
3112 static char *keywords[] = {"path", NULL};
3113 int fd = -1;
3114
3115#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3116 PyObject *v;
3117 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3118 BOOL result;
3119 WIN32_FIND_DATA FileData;
3120 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
3121 char *bufptr = namebuf;
3122 /* only claim to have space for MAX_PATH */
3123 Py_ssize_t len = sizeof(namebuf)-5;
3124 PyObject *po = NULL;
3125 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003126#else
3127 PyObject *v;
3128 DIR *dirp = NULL;
3129 struct dirent *ep;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003130 int return_str; /* if false, return bytes */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003131#endif
3132
3133 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003134 path.function_name = "listdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003135 path.nullable = 1;
3136#ifdef HAVE_FDOPENDIR
3137 path.allow_fd = 1;
3138 path.fd = -1;
3139#endif
3140 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3141 path_converter, &path
3142 ))
3143 return NULL;
3144
Victor Stinner8c62be82010-05-06 00:08:46 +00003145 /* XXX Should redo this putting the (now four) versions of opendir
3146 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003147#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003148 if (!path.narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003149 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003150 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003151
Larry Hastings9cf065c2012-06-22 16:30:09 -07003152 if (!path.wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003153 po_wchars = L".";
3154 len = 1;
3155 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003156 po_wchars = path.wide;
3157 len = wcslen(path.wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003158 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003159 /* The +5 is so we can append "\\*.*\0" */
Victor Stinner8c62be82010-05-06 00:08:46 +00003160 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
3161 if (!wnamebuf) {
3162 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003163 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003164 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003165 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003166 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003167 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00003168 if (wch != L'/' && wch != L'\\' && wch != L':')
3169 wnamebuf[len++] = L'\\';
3170 wcscpy(wnamebuf + len, L"*.*");
3171 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003172 if ((list = PyList_New(0)) == NULL) {
3173 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003174 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003175 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003176 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003177 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003178 if (hFindFile == INVALID_HANDLE_VALUE) {
3179 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003180 if (error == ERROR_FILE_NOT_FOUND)
3181 goto exit;
3182 Py_DECREF(list);
Victor Stinnerb024e842012-10-31 22:24:06 +01003183 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003184 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003185 }
3186 do {
3187 /* Skip over . and .. */
3188 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3189 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003190 v = PyUnicode_FromWideChar(wFileData.cFileName,
3191 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003192 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003193 Py_DECREF(list);
3194 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003195 break;
3196 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003197 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003198 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003199 Py_DECREF(list);
3200 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003201 break;
3202 }
3203 Py_DECREF(v);
3204 }
3205 Py_BEGIN_ALLOW_THREADS
3206 result = FindNextFileW(hFindFile, &wFileData);
3207 Py_END_ALLOW_THREADS
3208 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3209 it got to the end of the directory. */
3210 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003211 Py_DECREF(list);
Victor Stinnerb024e842012-10-31 22:24:06 +01003212 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003213 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003214 }
3215 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003216
Larry Hastings9cf065c2012-06-22 16:30:09 -07003217 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003218 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003219 strcpy(namebuf, path.narrow);
3220 len = path.length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003221 if (len > 0) {
3222 char ch = namebuf[len-1];
3223 if (ch != SEP && ch != ALTSEP && ch != ':')
3224 namebuf[len++] = '/';
3225 strcpy(namebuf + len, "*.*");
3226 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003227
Larry Hastings9cf065c2012-06-22 16:30:09 -07003228 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003229 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003230
Antoine Pitroub73caab2010-08-09 23:39:31 +00003231 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003232 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003233 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003234 if (hFindFile == INVALID_HANDLE_VALUE) {
3235 int error = GetLastError();
3236 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003237 goto exit;
3238 Py_DECREF(list);
Victor Stinnerb024e842012-10-31 22:24:06 +01003239 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003240 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003241 }
3242 do {
3243 /* Skip over . and .. */
3244 if (strcmp(FileData.cFileName, ".") != 0 &&
3245 strcmp(FileData.cFileName, "..") != 0) {
3246 v = PyBytes_FromString(FileData.cFileName);
3247 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003248 Py_DECREF(list);
3249 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003250 break;
3251 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003252 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003253 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003254 Py_DECREF(list);
3255 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003256 break;
3257 }
3258 Py_DECREF(v);
3259 }
3260 Py_BEGIN_ALLOW_THREADS
3261 result = FindNextFile(hFindFile, &FileData);
3262 Py_END_ALLOW_THREADS
3263 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3264 it got to the end of the directory. */
3265 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003266 Py_DECREF(list);
Victor Stinnerb024e842012-10-31 22:24:06 +01003267 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003268 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003269 }
3270 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003271
Larry Hastings9cf065c2012-06-22 16:30:09 -07003272exit:
3273 if (hFindFile != INVALID_HANDLE_VALUE) {
3274 if (FindClose(hFindFile) == FALSE) {
3275 if (list != NULL) {
3276 Py_DECREF(list);
Victor Stinnerb024e842012-10-31 22:24:06 +01003277 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003278 }
3279 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003280 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003281 if (wnamebuf)
3282 free(wnamebuf);
3283 path_cleanup(&path);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003284
Larry Hastings9cf065c2012-06-22 16:30:09 -07003285 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003286
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003287#else
Just van Rossum96b1c902003-03-03 17:32:15 +00003288
Victor Stinner8c62be82010-05-06 00:08:46 +00003289 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003290#ifdef HAVE_FDOPENDIR
3291 if (path.fd != -1) {
3292 /* closedir() closes the FD, so we duplicate it */
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003293 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003294 fd = dup(path.fd);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003295 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003296
3297 if (fd == -1) {
3298 list = posix_error();
3299 goto exit;
3300 }
3301
Larry Hastingsfdaea062012-06-25 04:42:23 -07003302 return_str = 1;
3303
Larry Hastings9cf065c2012-06-22 16:30:09 -07003304 Py_BEGIN_ALLOW_THREADS
3305 dirp = fdopendir(fd);
3306 Py_END_ALLOW_THREADS
3307 }
3308 else
3309#endif
3310 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003311 char *name;
3312 if (path.narrow) {
3313 name = path.narrow;
3314 /* only return bytes if they specified a bytes object */
3315 return_str = !(PyBytes_Check(path.object));
3316 }
3317 else {
3318 name = ".";
3319 return_str = 1;
3320 }
3321
Larry Hastings9cf065c2012-06-22 16:30:09 -07003322 Py_BEGIN_ALLOW_THREADS
3323 dirp = opendir(name);
3324 Py_END_ALLOW_THREADS
3325 }
3326
3327 if (dirp == NULL) {
Victor Stinner292c8352012-10-30 02:17:38 +01003328 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003329 goto exit;
3330 }
3331 if ((list = PyList_New(0)) == NULL) {
3332 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003333 }
3334 for (;;) {
3335 errno = 0;
3336 Py_BEGIN_ALLOW_THREADS
3337 ep = readdir(dirp);
3338 Py_END_ALLOW_THREADS
3339 if (ep == NULL) {
3340 if (errno == 0) {
3341 break;
3342 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003343 Py_DECREF(list);
Victor Stinner292c8352012-10-30 02:17:38 +01003344 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003345 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003346 }
3347 }
3348 if (ep->d_name[0] == '.' &&
3349 (NAMLEN(ep) == 1 ||
3350 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3351 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003352 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003353 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3354 else
3355 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003356 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003357 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003358 break;
3359 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003360 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003361 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003362 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003363 break;
3364 }
3365 Py_DECREF(v);
3366 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003367
Larry Hastings9cf065c2012-06-22 16:30:09 -07003368exit:
3369 if (dirp != NULL) {
3370 Py_BEGIN_ALLOW_THREADS
3371 if (fd > -1)
3372 rewinddir(dirp);
3373 closedir(dirp);
3374 Py_END_ALLOW_THREADS
3375 }
3376
3377 path_cleanup(&path);
3378
3379 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003380
Tim Peters0bb44a42000-09-15 07:44:49 +00003381#endif /* which OS */
3382} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003383
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003384#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003385/* A helper function for abspath on win32 */
3386static PyObject *
3387posix__getfullpathname(PyObject *self, PyObject *args)
3388{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003389 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003390 char outbuf[MAX_PATH*2];
3391 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003392 PyObject *po;
3393
3394 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3395 {
3396 wchar_t *wpath;
3397 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3398 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003399 DWORD result;
3400 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003401
3402 wpath = PyUnicode_AsUnicode(po);
3403 if (wpath == NULL)
3404 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003405 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003406 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003407 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003408 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003409 woutbufp = malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003410 if (!woutbufp)
3411 return PyErr_NoMemory();
3412 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3413 }
3414 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003415 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003416 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003417 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003418 if (woutbufp != woutbuf)
3419 free(woutbufp);
3420 return v;
3421 }
3422 /* Drop the argument parsing error as narrow strings
3423 are also valid. */
3424 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003425
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003426 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3427 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003428 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003429 if (win32_warn_bytes_api())
3430 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003431 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003432 outbuf, &temp)) {
3433 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003434 return NULL;
3435 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003436 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3437 return PyUnicode_Decode(outbuf, strlen(outbuf),
3438 Py_FileSystemDefaultEncoding, NULL);
3439 }
3440 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003441} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003442
Brian Curtind25aef52011-06-13 15:16:04 -05003443
Brian Curtinf5e76d02010-11-24 13:14:05 +00003444
Brian Curtind40e6f72010-07-08 21:39:08 +00003445/* A helper function for samepath on windows */
3446static PyObject *
3447posix__getfinalpathname(PyObject *self, PyObject *args)
3448{
3449 HANDLE hFile;
3450 int buf_size;
3451 wchar_t *target_path;
3452 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003453 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003454 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003455
Victor Stinnereb5657a2011-09-30 01:44:27 +02003456 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003457 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003458 path = PyUnicode_AsUnicode(po);
3459 if (path == NULL)
3460 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003461
3462 if(!check_GetFinalPathNameByHandle()) {
3463 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3464 NotImplementedError. */
3465 return PyErr_Format(PyExc_NotImplementedError,
3466 "GetFinalPathNameByHandle not available on this platform");
3467 }
3468
3469 hFile = CreateFileW(
3470 path,
3471 0, /* desired access */
3472 0, /* share mode */
3473 NULL, /* security attributes */
3474 OPEN_EXISTING,
3475 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3476 FILE_FLAG_BACKUP_SEMANTICS,
3477 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003478
Victor Stinnereb5657a2011-09-30 01:44:27 +02003479 if(hFile == INVALID_HANDLE_VALUE)
3480 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003481
3482 /* We have a good handle to the target, use it to determine the
3483 target path name. */
3484 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3485
3486 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003487 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003488
3489 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
3490 if(!target_path)
3491 return PyErr_NoMemory();
3492
3493 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3494 buf_size, VOLUME_NAME_DOS);
3495 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003496 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003497
3498 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003499 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003500
3501 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003502 result = PyUnicode_FromWideChar(target_path, result_length);
Brian Curtind40e6f72010-07-08 21:39:08 +00003503 free(target_path);
3504 return result;
3505
3506} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003507
Brian Curtin95d028f2011-06-09 09:10:38 -05003508PyDoc_STRVAR(posix__isdir__doc__,
3509"Return true if the pathname refers to an existing directory.");
3510
Brian Curtin9c669cc2011-06-08 18:17:18 -05003511static PyObject *
3512posix__isdir(PyObject *self, PyObject *args)
3513{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003514 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003515 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003516 DWORD attributes;
3517
3518 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003519 wchar_t *wpath = PyUnicode_AsUnicode(po);
3520 if (wpath == NULL)
3521 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003522
3523 attributes = GetFileAttributesW(wpath);
3524 if (attributes == INVALID_FILE_ATTRIBUTES)
3525 Py_RETURN_FALSE;
3526 goto check;
3527 }
3528 /* Drop the argument parsing error as narrow strings
3529 are also valid. */
3530 PyErr_Clear();
3531
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003532 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003533 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003534 if (win32_warn_bytes_api())
3535 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003536 attributes = GetFileAttributesA(path);
3537 if (attributes == INVALID_FILE_ATTRIBUTES)
3538 Py_RETURN_FALSE;
3539
3540check:
3541 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3542 Py_RETURN_TRUE;
3543 else
3544 Py_RETURN_FALSE;
3545}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003546#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003547
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003548PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003549"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3550Create a directory.\n\
3551\n\
3552If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3553 and path should be relative; path will then be relative to that directory.\n\
3554dir_fd may not be implemented on your platform.\n\
3555 If it is unavailable, using it will raise a NotImplementedError.\n\
3556\n\
3557The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003558
Barry Warsaw53699e91996-12-10 23:23:01 +00003559static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003560posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003561{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003562 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003563 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003564 int dir_fd = DEFAULT_DIR_FD;
3565 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
3566 PyObject *return_value = NULL;
3567 int result;
3568
3569 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003570 path.function_name = "mkdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003571 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
3572 path_converter, &path, &mode,
3573#ifdef HAVE_MKDIRAT
3574 dir_fd_converter, &dir_fd
3575#else
3576 dir_fd_unavailable, &dir_fd
3577#endif
3578 ))
3579 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003580
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003581#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003582 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003583 if (path.wide)
3584 result = CreateDirectoryW(path.wide, NULL);
3585 else
3586 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003587 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003588
Larry Hastings9cf065c2012-06-22 16:30:09 -07003589 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003590 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003591 goto exit;
3592 }
3593#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003594 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003595#if HAVE_MKDIRAT
3596 if (dir_fd != DEFAULT_DIR_FD)
3597 result = mkdirat(dir_fd, path.narrow, mode);
3598 else
3599#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003600#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003601 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003602#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003603 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003604#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003605 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003606 if (result < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01003607 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003608 goto exit;
3609 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00003610#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003611 return_value = Py_None;
3612 Py_INCREF(Py_None);
3613exit:
3614 path_cleanup(&path);
3615 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003616}
3617
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003618
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003619/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3620#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003621#include <sys/resource.h>
3622#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003623
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003624
3625#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003626PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003627"nice(inc) -> new_priority\n\n\
3628Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003629
Barry Warsaw53699e91996-12-10 23:23:01 +00003630static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003631posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00003632{
Victor Stinner8c62be82010-05-06 00:08:46 +00003633 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00003634
Victor Stinner8c62be82010-05-06 00:08:46 +00003635 if (!PyArg_ParseTuple(args, "i:nice", &increment))
3636 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003637
Victor Stinner8c62be82010-05-06 00:08:46 +00003638 /* There are two flavours of 'nice': one that returns the new
3639 priority (as required by almost all standards out there) and the
3640 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3641 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003642
Victor Stinner8c62be82010-05-06 00:08:46 +00003643 If we are of the nice family that returns the new priority, we
3644 need to clear errno before the call, and check if errno is filled
3645 before calling posix_error() on a returnvalue of -1, because the
3646 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003647
Victor Stinner8c62be82010-05-06 00:08:46 +00003648 errno = 0;
3649 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003650#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003651 if (value == 0)
3652 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003653#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003654 if (value == -1 && errno != 0)
3655 /* either nice() or getpriority() returned an error */
3656 return posix_error();
3657 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003658}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003659#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003660
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003661
3662#ifdef HAVE_GETPRIORITY
3663PyDoc_STRVAR(posix_getpriority__doc__,
3664"getpriority(which, who) -> current_priority\n\n\
3665Get program scheduling priority.");
3666
3667static PyObject *
3668posix_getpriority(PyObject *self, PyObject *args)
3669{
3670 int which, who, retval;
3671
3672 if (!PyArg_ParseTuple(args, "ii", &which, &who))
3673 return NULL;
3674 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003675 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003676 if (errno != 0)
3677 return posix_error();
3678 return PyLong_FromLong((long)retval);
3679}
3680#endif /* HAVE_GETPRIORITY */
3681
3682
3683#ifdef HAVE_SETPRIORITY
3684PyDoc_STRVAR(posix_setpriority__doc__,
3685"setpriority(which, who, prio) -> None\n\n\
3686Set program scheduling priority.");
3687
3688static PyObject *
3689posix_setpriority(PyObject *self, PyObject *args)
3690{
3691 int which, who, prio, retval;
3692
3693 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
3694 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003695 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003696 if (retval == -1)
3697 return posix_error();
3698 Py_RETURN_NONE;
3699}
3700#endif /* HAVE_SETPRIORITY */
3701
3702
Barry Warsaw53699e91996-12-10 23:23:01 +00003703static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003704internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003705{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003706 char *function_name = is_replace ? "replace" : "rename";
3707 path_t src;
3708 path_t dst;
3709 int src_dir_fd = DEFAULT_DIR_FD;
3710 int dst_dir_fd = DEFAULT_DIR_FD;
3711 int dir_fd_specified;
3712 PyObject *return_value = NULL;
3713 char format[24];
3714 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
3715
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003716#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003717 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003718 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003719#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003720 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003721#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003722
3723 memset(&src, 0, sizeof(src));
3724 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01003725 src.function_name = function_name;
3726 dst.function_name = function_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003727 strcpy(format, "O&O&|$O&O&:");
3728 strcat(format, function_name);
3729 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
3730 path_converter, &src,
3731 path_converter, &dst,
3732 dir_fd_converter, &src_dir_fd,
3733 dir_fd_converter, &dst_dir_fd))
3734 return NULL;
3735
3736 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
3737 (dst_dir_fd != DEFAULT_DIR_FD);
3738#ifndef HAVE_RENAMEAT
3739 if (dir_fd_specified) {
3740 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
3741 goto exit;
3742 }
3743#endif
3744
3745 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3746 PyErr_Format(PyExc_ValueError,
3747 "%s: src and dst must be the same type", function_name);
3748 goto exit;
3749 }
3750
3751#ifdef MS_WINDOWS
3752 Py_BEGIN_ALLOW_THREADS
3753 if (src.wide)
3754 result = MoveFileExW(src.wide, dst.wide, flags);
3755 else
3756 result = MoveFileExA(src.narrow, dst.narrow, flags);
3757 Py_END_ALLOW_THREADS
3758
3759 if (!result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01003760 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003761 goto exit;
3762 }
3763
3764#else
3765 Py_BEGIN_ALLOW_THREADS
3766#ifdef HAVE_RENAMEAT
3767 if (dir_fd_specified)
3768 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
3769 else
3770#endif
3771 result = rename(src.narrow, dst.narrow);
3772 Py_END_ALLOW_THREADS
3773
3774 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003775 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003776 goto exit;
3777 }
3778#endif
3779
3780 Py_INCREF(Py_None);
3781 return_value = Py_None;
3782exit:
3783 path_cleanup(&src);
3784 path_cleanup(&dst);
3785 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003786}
3787
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003788PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003789"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
3790Rename a file or directory.\n\
3791\n\
3792If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3793 descriptor open to a directory, and the respective path string (src or dst)\n\
3794 should be relative; the path will then be relative to that directory.\n\
3795src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
3796 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003797
3798static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003799posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003800{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003801 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003802}
3803
3804PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003805"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
3806Rename a file or directory, overwriting the destination.\n\
3807\n\
3808If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3809 descriptor open to a directory, and the respective path string (src or dst)\n\
3810 should be relative; the path will then be relative to that directory.\n\
3811src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
3812 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003813
3814static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003815posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003816{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003817 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003818}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003819
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003820PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003821"rmdir(path, *, dir_fd=None)\n\n\
3822Remove a directory.\n\
3823\n\
3824If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3825 and path should be relative; path will then be relative to that directory.\n\
3826dir_fd may not be implemented on your platform.\n\
3827 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003828
Barry Warsaw53699e91996-12-10 23:23:01 +00003829static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003830posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003831{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003832 path_t path;
3833 int dir_fd = DEFAULT_DIR_FD;
3834 static char *keywords[] = {"path", "dir_fd", NULL};
3835 int result;
3836 PyObject *return_value = NULL;
3837
3838 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003839 path.function_name = "rmdir";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003840 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
3841 path_converter, &path,
3842#ifdef HAVE_UNLINKAT
3843 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003844#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003845 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003846#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003847 ))
3848 return NULL;
3849
3850 Py_BEGIN_ALLOW_THREADS
3851#ifdef MS_WINDOWS
3852 if (path.wide)
3853 result = RemoveDirectoryW(path.wide);
3854 else
3855 result = RemoveDirectoryA(path.narrow);
3856 result = !result; /* Windows, success=1, UNIX, success=0 */
3857#else
3858#ifdef HAVE_UNLINKAT
3859 if (dir_fd != DEFAULT_DIR_FD)
3860 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
3861 else
3862#endif
3863 result = rmdir(path.narrow);
3864#endif
3865 Py_END_ALLOW_THREADS
3866
3867 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003868 return_value = path_error(&path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003869 goto exit;
3870 }
3871
3872 return_value = Py_None;
3873 Py_INCREF(Py_None);
3874
3875exit:
3876 path_cleanup(&path);
3877 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003878}
3879
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003880
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003881#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003882PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003883"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003884Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003885
Barry Warsaw53699e91996-12-10 23:23:01 +00003886static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003887posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003888{
Victor Stinner8c62be82010-05-06 00:08:46 +00003889 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00003890#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003891 wchar_t *command;
3892 if (!PyArg_ParseTuple(args, "u:system", &command))
3893 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003894
Victor Stinner8c62be82010-05-06 00:08:46 +00003895 Py_BEGIN_ALLOW_THREADS
3896 sts = _wsystem(command);
3897 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00003898#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003899 PyObject *command_obj;
3900 char *command;
3901 if (!PyArg_ParseTuple(args, "O&:system",
3902 PyUnicode_FSConverter, &command_obj))
3903 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003904
Victor Stinner8c62be82010-05-06 00:08:46 +00003905 command = PyBytes_AsString(command_obj);
3906 Py_BEGIN_ALLOW_THREADS
3907 sts = system(command);
3908 Py_END_ALLOW_THREADS
3909 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00003910#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003911 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003912}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003913#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003914
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003915
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003916PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003917"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003918Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003919
Barry Warsaw53699e91996-12-10 23:23:01 +00003920static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003921posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003922{
Victor Stinner8c62be82010-05-06 00:08:46 +00003923 int i;
3924 if (!PyArg_ParseTuple(args, "i:umask", &i))
3925 return NULL;
3926 i = (int)umask(i);
3927 if (i < 0)
3928 return posix_error();
3929 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003930}
3931
Brian Curtind40e6f72010-07-08 21:39:08 +00003932#ifdef MS_WINDOWS
3933
3934/* override the default DeleteFileW behavior so that directory
3935symlinks can be removed with this function, the same as with
3936Unix symlinks */
3937BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
3938{
3939 WIN32_FILE_ATTRIBUTE_DATA info;
3940 WIN32_FIND_DATAW find_data;
3941 HANDLE find_data_handle;
3942 int is_directory = 0;
3943 int is_link = 0;
3944
3945 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
3946 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003947
Brian Curtind40e6f72010-07-08 21:39:08 +00003948 /* Get WIN32_FIND_DATA structure for the path to determine if
3949 it is a symlink */
3950 if(is_directory &&
3951 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
3952 find_data_handle = FindFirstFileW(lpFileName, &find_data);
3953
3954 if(find_data_handle != INVALID_HANDLE_VALUE) {
3955 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
3956 FindClose(find_data_handle);
3957 }
3958 }
3959 }
3960
3961 if (is_directory && is_link)
3962 return RemoveDirectoryW(lpFileName);
3963
3964 return DeleteFileW(lpFileName);
3965}
3966#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003967
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003968PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003969"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003970Remove a file (same as remove()).\n\
3971\n\
3972If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3973 and path should be relative; path will then be relative to that directory.\n\
3974dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003975 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003976
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003977PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003978"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003979Remove a file (same as unlink()).\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\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003984 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 Hastings9cf065c2012-06-22 16:30:09 -07003987posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003988{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003989 path_t path;
3990 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003991 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07003992 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 = "unlink";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003997 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003998 path_converter, &path,
3999#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004000 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 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004005 return NULL;
4006
4007 Py_BEGIN_ALLOW_THREADS
4008#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004009 if (path.wide)
4010 result = Py_DeleteFileW(path.wide);
4011 else
4012 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004013 result = !result; /* Windows, success=1, UNIX, success=0 */
4014#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004015#ifdef HAVE_UNLINKAT
4016 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004017 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004018 else
4019#endif /* HAVE_UNLINKAT */
4020 result = unlink(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 Hastings9cf065c2012-06-22 16:30:09 -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
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004038PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004039"uname() -> uname_result\n\n\
4040Return an object identifying the current operating system.\n\
4041The object behaves like a named tuple with the following fields:\n\
4042 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004043
Larry Hastings605a62d2012-06-24 04:33:36 -07004044static PyStructSequence_Field uname_result_fields[] = {
4045 {"sysname", "operating system name"},
4046 {"nodename", "name of machine on network (implementation-defined)"},
4047 {"release", "operating system release"},
4048 {"version", "operating system version"},
4049 {"machine", "hardware identifier"},
4050 {NULL}
4051};
4052
4053PyDoc_STRVAR(uname_result__doc__,
4054"uname_result: Result from os.uname().\n\n\
4055This object may be accessed either as a tuple of\n\
4056 (sysname, nodename, release, version, machine),\n\
4057or via the attributes sysname, nodename, release, version, and machine.\n\
4058\n\
4059See os.uname for more information.");
4060
4061static PyStructSequence_Desc uname_result_desc = {
4062 "uname_result", /* name */
4063 uname_result__doc__, /* doc */
4064 uname_result_fields,
4065 5
4066};
4067
4068static PyTypeObject UnameResultType;
4069
4070
4071#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004072static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004073posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004074{
Victor Stinner8c62be82010-05-06 00:08:46 +00004075 struct utsname u;
4076 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004077 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004078
Victor Stinner8c62be82010-05-06 00:08:46 +00004079 Py_BEGIN_ALLOW_THREADS
4080 res = uname(&u);
4081 Py_END_ALLOW_THREADS
4082 if (res < 0)
4083 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004084
4085 value = PyStructSequence_New(&UnameResultType);
4086 if (value == NULL)
4087 return NULL;
4088
4089#define SET(i, field) \
4090 { \
4091 PyObject *o = PyUnicode_DecodeASCII(field, strlen(field), NULL); \
4092 if (!o) { \
4093 Py_DECREF(value); \
4094 return NULL; \
4095 } \
4096 PyStructSequence_SET_ITEM(value, i, o); \
4097 } \
4098
4099 SET(0, u.sysname);
4100 SET(1, u.nodename);
4101 SET(2, u.release);
4102 SET(3, u.version);
4103 SET(4, u.machine);
4104
4105#undef SET
4106
4107 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004108}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004109#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004110
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004111
Larry Hastings9cf065c2012-06-22 16:30:09 -07004112PyDoc_STRVAR(posix_utime__doc__,
4113"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4114Set the access and modified time of path.\n\
4115\n\
4116path may always be specified as a string.\n\
4117On some platforms, path may also be specified as an open file descriptor.\n\
4118 If this functionality is unavailable, using it raises an exception.\n\
4119\n\
4120If times is not None, it must be a tuple (atime, mtime);\n\
4121 atime and mtime should be expressed as float seconds since the epoch.\n\
4122If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4123 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4124 since the epoch.\n\
4125If both times and ns are None, utime uses the current time.\n\
4126Specifying tuples for both times and ns is an error.\n\
4127\n\
4128If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4129 and path should be relative; path will then be relative to that directory.\n\
4130If follow_symlinks is False, and the last element of the path is a symbolic\n\
4131 link, utime will modify the symbolic link itself instead of the file the\n\
4132 link points to.\n\
4133It is an error to use dir_fd or follow_symlinks when specifying path\n\
4134 as an open file descriptor.\n\
4135dir_fd and follow_symlinks may not be available on your platform.\n\
4136 If they are unavailable, using them will raise a NotImplementedError.");
4137
4138typedef struct {
4139 int now;
4140 time_t atime_s;
4141 long atime_ns;
4142 time_t mtime_s;
4143 long mtime_ns;
4144} utime_t;
4145
4146/*
4147 * these macros assume that "utime" is a pointer to a utime_t
4148 * they also intentionally leak the declaration of a pointer named "time"
4149 */
4150#define UTIME_TO_TIMESPEC \
4151 struct timespec ts[2]; \
4152 struct timespec *time; \
4153 if (utime->now) \
4154 time = NULL; \
4155 else { \
4156 ts[0].tv_sec = utime->atime_s; \
4157 ts[0].tv_nsec = utime->atime_ns; \
4158 ts[1].tv_sec = utime->mtime_s; \
4159 ts[1].tv_nsec = utime->mtime_ns; \
4160 time = ts; \
4161 } \
4162
4163#define UTIME_TO_TIMEVAL \
4164 struct timeval tv[2]; \
4165 struct timeval *time; \
4166 if (utime->now) \
4167 time = NULL; \
4168 else { \
4169 tv[0].tv_sec = utime->atime_s; \
4170 tv[0].tv_usec = utime->atime_ns / 1000; \
4171 tv[1].tv_sec = utime->mtime_s; \
4172 tv[1].tv_usec = utime->mtime_ns / 1000; \
4173 time = tv; \
4174 } \
4175
4176#define UTIME_TO_UTIMBUF \
4177 struct utimbuf u[2]; \
4178 struct utimbuf *time; \
4179 if (utime->now) \
4180 time = NULL; \
4181 else { \
4182 u.actime = utime->atime_s; \
4183 u.modtime = utime->mtime_s; \
4184 time = u; \
4185 }
4186
4187#define UTIME_TO_TIME_T \
4188 time_t timet[2]; \
4189 struct timet time; \
4190 if (utime->now) \
4191 time = NULL; \
4192 else { \
4193 timet[0] = utime->atime_s; \
4194 timet[1] = utime->mtime_s; \
4195 time = &timet; \
4196 } \
4197
4198
4199#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4200
4201#if UTIME_HAVE_DIR_FD
4202
4203static int
4204utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4205{
4206#ifdef HAVE_UTIMENSAT
4207 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4208 UTIME_TO_TIMESPEC;
4209 return utimensat(dir_fd, path, time, flags);
4210#elif defined(HAVE_FUTIMESAT)
4211 UTIME_TO_TIMEVAL;
4212 /*
4213 * follow_symlinks will never be false here;
4214 * we only allow !follow_symlinks and dir_fd together
4215 * if we have utimensat()
4216 */
4217 assert(follow_symlinks);
4218 return futimesat(dir_fd, path, time);
4219#endif
4220}
4221
4222#endif
4223
4224#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4225
4226#if UTIME_HAVE_FD
4227
4228static int
4229utime_fd(utime_t *utime, int fd)
4230{
4231#ifdef HAVE_FUTIMENS
4232 UTIME_TO_TIMESPEC;
4233 return futimens(fd, time);
4234#else
4235 UTIME_TO_TIMEVAL;
4236 return futimes(fd, time);
4237#endif
4238}
4239
4240#endif
4241
4242
4243#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4244 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4245
4246#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4247
4248static int
4249utime_nofollow_symlinks(utime_t *utime, char *path)
4250{
4251#ifdef HAVE_UTIMENSAT
4252 UTIME_TO_TIMESPEC;
4253 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4254#else
4255 UTIME_TO_TIMEVAL;
4256 return lutimes(path, time);
4257#endif
4258}
4259
4260#endif
4261
4262#ifndef MS_WINDOWS
4263
4264static int
4265utime_default(utime_t *utime, char *path)
4266{
4267#ifdef HAVE_UTIMENSAT
4268 UTIME_TO_TIMESPEC;
4269 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4270#elif defined(HAVE_UTIMES)
4271 UTIME_TO_TIMEVAL;
4272 return utimes(path, time);
4273#elif defined(HAVE_UTIME_H)
4274 UTIME_TO_UTIMBUF;
4275 return utime(path, time);
4276#else
4277 UTIME_TO_TIME_T;
4278 return utime(path, time);
4279#endif
4280}
4281
4282#endif
4283
Larry Hastings76ad59b2012-05-03 00:30:07 -07004284static int
4285split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4286{
4287 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004288 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004289 divmod = PyNumber_Divmod(py_long, billion);
4290 if (!divmod)
4291 goto exit;
4292 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4293 if ((*s == -1) && PyErr_Occurred())
4294 goto exit;
4295 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004296 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004297 goto exit;
4298
4299 result = 1;
4300exit:
4301 Py_XDECREF(divmod);
4302 return result;
4303}
4304
Larry Hastings9cf065c2012-06-22 16:30:09 -07004305static PyObject *
4306posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004307{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004308 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004309 PyObject *times = NULL;
4310 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004311 int dir_fd = DEFAULT_DIR_FD;
4312 int follow_symlinks = 1;
4313 char *keywords[] = {"path", "times", "ns", "dir_fd",
4314 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004315
Larry Hastings9cf065c2012-06-22 16:30:09 -07004316 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004317
Larry Hastings9cf065c2012-06-22 16:30:09 -07004318#ifdef MS_WINDOWS
4319 HANDLE hFile;
4320 FILETIME atime, mtime;
4321#else
4322 int result;
4323#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004324
Larry Hastings9cf065c2012-06-22 16:30:09 -07004325 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004326
Larry Hastings9cf065c2012-06-22 16:30:09 -07004327 memset(&path, 0, sizeof(path));
Victor Stinnerb024e842012-10-31 22:24:06 +01004328 path.function_name = "utime";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004329#if UTIME_HAVE_FD
4330 path.allow_fd = 1;
4331#endif
4332 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4333 "O&|O$OO&p:utime", keywords,
4334 path_converter, &path,
4335 &times, &ns,
4336#if UTIME_HAVE_DIR_FD
4337 dir_fd_converter, &dir_fd,
4338#else
4339 dir_fd_unavailable, &dir_fd,
4340#endif
4341 &follow_symlinks
4342 ))
4343 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004344
Larry Hastings9cf065c2012-06-22 16:30:09 -07004345 if (times && (times != Py_None) && ns) {
4346 PyErr_SetString(PyExc_ValueError,
4347 "utime: you may specify either 'times'"
4348 " or 'ns' but not both");
4349 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004350 }
4351
4352 if (times && (times != Py_None)) {
4353 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004354 PyErr_SetString(PyExc_TypeError,
4355 "utime: 'times' must be either"
4356 " a tuple of two ints or None");
4357 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004358 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004359 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004360 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004361 &utime.atime_s, &utime.atime_ns) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004362 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004363 &utime.mtime_s, &utime.mtime_ns) == -1) {
4364 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004365 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004366 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004367 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004368 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004369 PyErr_SetString(PyExc_TypeError,
4370 "utime: 'ns' must be a tuple of two ints");
4371 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004372 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004373 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004374 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004375 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004376 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004377 &utime.mtime_s, &utime.mtime_ns)) {
4378 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004379 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004380 }
4381 else {
4382 /* times and ns are both None/unspecified. use "now". */
4383 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004384 }
4385
Larry Hastings9cf065c2012-06-22 16:30:09 -07004386#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4387 if (follow_symlinks_specified("utime", follow_symlinks))
4388 goto exit;
4389#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004390
Larry Hastings9cf065c2012-06-22 16:30:09 -07004391 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4392 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4393 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4394 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004395
Larry Hastings9cf065c2012-06-22 16:30:09 -07004396#if !defined(HAVE_UTIMENSAT)
4397 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004398 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004399 "utime: cannot use dir_fd and follow_symlinks "
4400 "together on this platform");
4401 goto exit;
4402 }
4403#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004404
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004405#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004406 Py_BEGIN_ALLOW_THREADS
4407 if (path.wide)
4408 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004409 NULL, OPEN_EXISTING,
4410 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004411 else
4412 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004413 NULL, OPEN_EXISTING,
4414 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004415 Py_END_ALLOW_THREADS
4416 if (hFile == INVALID_HANDLE_VALUE) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004417 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004418 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004419 }
4420
Larry Hastings9cf065c2012-06-22 16:30:09 -07004421 if (utime.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004422 SYSTEMTIME now;
4423 GetSystemTime(&now);
4424 if (!SystemTimeToFileTime(&now, &mtime) ||
4425 !SystemTimeToFileTime(&now, &atime)) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004426 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004427 goto exit;
Stefan Krah0e803b32010-11-26 16:16:47 +00004428 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004429 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004430 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004431 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4432 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004433 }
4434 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4435 /* Avoid putting the file name into the error here,
4436 as that may confuse the user into believing that
4437 something is wrong with the file, when it also
4438 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004439 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004440 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004441 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004442#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004443 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004444
Larry Hastings9cf065c2012-06-22 16:30:09 -07004445#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4446 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4447 result = utime_nofollow_symlinks(&utime, path.narrow);
4448 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004449#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004450
4451#if UTIME_HAVE_DIR_FD
4452 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4453 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4454 else
4455#endif
4456
4457#if UTIME_HAVE_FD
4458 if (path.fd != -1)
4459 result = utime_fd(&utime, path.fd);
4460 else
4461#endif
4462
4463 result = utime_default(&utime, path.narrow);
4464
4465 Py_END_ALLOW_THREADS
4466
4467 if (result < 0) {
4468 /* see previous comment about not putting filename in error here */
4469 return_value = posix_error();
4470 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004471 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004472
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004473#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004474
4475 Py_INCREF(Py_None);
4476 return_value = Py_None;
4477
4478exit:
4479 path_cleanup(&path);
4480#ifdef MS_WINDOWS
4481 if (hFile != INVALID_HANDLE_VALUE)
4482 CloseHandle(hFile);
4483#endif
4484 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004485}
4486
Guido van Rossum3b066191991-06-04 19:40:25 +00004487/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004488
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004489PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004490"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004491Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004492
Barry Warsaw53699e91996-12-10 23:23:01 +00004493static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004494posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004495{
Victor Stinner8c62be82010-05-06 00:08:46 +00004496 int sts;
4497 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
4498 return NULL;
4499 _exit(sts);
4500 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004501}
4502
Martin v. Löwis114619e2002-10-07 06:44:21 +00004503#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4504static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004505free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004506{
Victor Stinner8c62be82010-05-06 00:08:46 +00004507 Py_ssize_t i;
4508 for (i = 0; i < count; i++)
4509 PyMem_Free(array[i]);
4510 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004511}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004512
Antoine Pitrou69f71142009-05-24 21:25:49 +00004513static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004514int fsconvert_strdup(PyObject *o, char**out)
4515{
Victor Stinner8c62be82010-05-06 00:08:46 +00004516 PyObject *bytes;
4517 Py_ssize_t size;
4518 if (!PyUnicode_FSConverter(o, &bytes))
4519 return 0;
4520 size = PyBytes_GET_SIZE(bytes);
4521 *out = PyMem_Malloc(size+1);
4522 if (!*out)
4523 return 0;
4524 memcpy(*out, PyBytes_AsString(bytes), size+1);
4525 Py_DECREF(bytes);
4526 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004527}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004528#endif
4529
Ross Lagerwall7807c352011-03-17 20:20:30 +02004530#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004531static char**
4532parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4533{
Victor Stinner8c62be82010-05-06 00:08:46 +00004534 char **envlist;
4535 Py_ssize_t i, pos, envc;
4536 PyObject *keys=NULL, *vals=NULL;
4537 PyObject *key, *val, *key2, *val2;
4538 char *p, *k, *v;
4539 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004540
Victor Stinner8c62be82010-05-06 00:08:46 +00004541 i = PyMapping_Size(env);
4542 if (i < 0)
4543 return NULL;
4544 envlist = PyMem_NEW(char *, i + 1);
4545 if (envlist == NULL) {
4546 PyErr_NoMemory();
4547 return NULL;
4548 }
4549 envc = 0;
4550 keys = PyMapping_Keys(env);
4551 vals = PyMapping_Values(env);
4552 if (!keys || !vals)
4553 goto error;
4554 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4555 PyErr_Format(PyExc_TypeError,
4556 "env.keys() or env.values() is not a list");
4557 goto error;
4558 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004559
Victor Stinner8c62be82010-05-06 00:08:46 +00004560 for (pos = 0; pos < i; pos++) {
4561 key = PyList_GetItem(keys, pos);
4562 val = PyList_GetItem(vals, pos);
4563 if (!key || !val)
4564 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004565
Victor Stinner8c62be82010-05-06 00:08:46 +00004566 if (PyUnicode_FSConverter(key, &key2) == 0)
4567 goto error;
4568 if (PyUnicode_FSConverter(val, &val2) == 0) {
4569 Py_DECREF(key2);
4570 goto error;
4571 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004572
Victor Stinner8c62be82010-05-06 00:08:46 +00004573 k = PyBytes_AsString(key2);
4574 v = PyBytes_AsString(val2);
4575 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004576
Victor Stinner8c62be82010-05-06 00:08:46 +00004577 p = PyMem_NEW(char, len);
4578 if (p == NULL) {
4579 PyErr_NoMemory();
4580 Py_DECREF(key2);
4581 Py_DECREF(val2);
4582 goto error;
4583 }
4584 PyOS_snprintf(p, len, "%s=%s", k, v);
4585 envlist[envc++] = p;
4586 Py_DECREF(key2);
4587 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00004588 }
4589 Py_DECREF(vals);
4590 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004591
Victor Stinner8c62be82010-05-06 00:08:46 +00004592 envlist[envc] = 0;
4593 *envc_ptr = envc;
4594 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004595
4596error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004597 Py_XDECREF(keys);
4598 Py_XDECREF(vals);
4599 while (--envc >= 0)
4600 PyMem_DEL(envlist[envc]);
4601 PyMem_DEL(envlist);
4602 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004603}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004604
Ross Lagerwall7807c352011-03-17 20:20:30 +02004605static char**
4606parse_arglist(PyObject* argv, Py_ssize_t *argc)
4607{
4608 int i;
4609 char **argvlist = PyMem_NEW(char *, *argc+1);
4610 if (argvlist == NULL) {
4611 PyErr_NoMemory();
4612 return NULL;
4613 }
4614 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004615 PyObject* item = PySequence_ITEM(argv, i);
4616 if (item == NULL)
4617 goto fail;
4618 if (!fsconvert_strdup(item, &argvlist[i])) {
4619 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004620 goto fail;
4621 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004622 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004623 }
4624 argvlist[*argc] = NULL;
4625 return argvlist;
4626fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004627 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004628 free_string_array(argvlist, *argc);
4629 return NULL;
4630}
4631#endif
4632
4633#ifdef HAVE_EXECV
4634PyDoc_STRVAR(posix_execv__doc__,
4635"execv(path, args)\n\n\
4636Execute an executable path with arguments, replacing current process.\n\
4637\n\
4638 path: path of executable file\n\
4639 args: tuple or list of strings");
4640
4641static PyObject *
4642posix_execv(PyObject *self, PyObject *args)
4643{
4644 PyObject *opath;
4645 char *path;
4646 PyObject *argv;
4647 char **argvlist;
4648 Py_ssize_t argc;
4649
4650 /* execv has two arguments: (path, argv), where
4651 argv is a list or tuple of strings. */
4652
4653 if (!PyArg_ParseTuple(args, "O&O:execv",
4654 PyUnicode_FSConverter,
4655 &opath, &argv))
4656 return NULL;
4657 path = PyBytes_AsString(opath);
4658 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4659 PyErr_SetString(PyExc_TypeError,
4660 "execv() arg 2 must be a tuple or list");
4661 Py_DECREF(opath);
4662 return NULL;
4663 }
4664 argc = PySequence_Size(argv);
4665 if (argc < 1) {
4666 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
4667 Py_DECREF(opath);
4668 return NULL;
4669 }
4670
4671 argvlist = parse_arglist(argv, &argc);
4672 if (argvlist == NULL) {
4673 Py_DECREF(opath);
4674 return NULL;
4675 }
4676
4677 execv(path, argvlist);
4678
4679 /* If we get here it's definitely an error */
4680
4681 free_string_array(argvlist, argc);
4682 Py_DECREF(opath);
4683 return posix_error();
4684}
4685
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004686PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004687"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004688Execute a path with arguments and environment, replacing current process.\n\
4689\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004690 path: path of executable file\n\
4691 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004692 env: dictionary of strings mapping to strings\n\
4693\n\
4694On some platforms, you may specify an open file descriptor for path;\n\
4695 execve will execute the program the file descriptor is open to.\n\
4696 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004697
Barry Warsaw53699e91996-12-10 23:23:01 +00004698static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004699posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004700{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004701 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004702 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004703 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004704 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004705 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004706 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004707
Victor Stinner8c62be82010-05-06 00:08:46 +00004708 /* execve has three arguments: (path, argv, env), where
4709 argv is a list or tuple of strings and env is a dictionary
4710 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004711
Larry Hastings9cf065c2012-06-22 16:30:09 -07004712 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004713 path.function_name = "execve";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004714#ifdef HAVE_FEXECVE
4715 path.allow_fd = 1;
4716#endif
4717 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
4718 path_converter, &path,
4719 &argv, &env
4720 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00004721 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004722
Ross Lagerwall7807c352011-03-17 20:20:30 +02004723 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004724 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004725 "execve: argv must be a tuple or list");
4726 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004727 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004728 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00004729 if (!PyMapping_Check(env)) {
4730 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004731 "execve: environment must be a mapping object");
4732 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004733 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004734
Ross Lagerwall7807c352011-03-17 20:20:30 +02004735 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004736 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004737 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004738 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004739
Victor Stinner8c62be82010-05-06 00:08:46 +00004740 envlist = parse_envlist(env, &envc);
4741 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02004742 goto fail;
4743
Larry Hastings9cf065c2012-06-22 16:30:09 -07004744#ifdef HAVE_FEXECVE
4745 if (path.fd > -1)
4746 fexecve(path.fd, argvlist, envlist);
4747 else
4748#endif
4749 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004750
4751 /* If we get here it's definitely an error */
4752
Victor Stinner292c8352012-10-30 02:17:38 +01004753 path_error(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004754
4755 while (--envc >= 0)
4756 PyMem_DEL(envlist[envc]);
4757 PyMem_DEL(envlist);
4758 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004759 if (argvlist)
4760 free_string_array(argvlist, argc);
4761 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004762 return NULL;
4763}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004764#endif /* HAVE_EXECV */
4765
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004766
Guido van Rossuma1065681999-01-25 23:20:23 +00004767#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004768PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004769"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004770Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004771\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004772 mode: mode of process creation\n\
4773 path: path of executable file\n\
4774 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004775
4776static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004777posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004778{
Victor Stinner8c62be82010-05-06 00:08:46 +00004779 PyObject *opath;
4780 char *path;
4781 PyObject *argv;
4782 char **argvlist;
4783 int mode, i;
4784 Py_ssize_t argc;
4785 Py_intptr_t spawnval;
4786 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00004787
Victor Stinner8c62be82010-05-06 00:08:46 +00004788 /* spawnv has three arguments: (mode, path, argv), where
4789 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004790
Victor Stinner8c62be82010-05-06 00:08:46 +00004791 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
4792 PyUnicode_FSConverter,
4793 &opath, &argv))
4794 return NULL;
4795 path = PyBytes_AsString(opath);
4796 if (PyList_Check(argv)) {
4797 argc = PyList_Size(argv);
4798 getitem = PyList_GetItem;
4799 }
4800 else if (PyTuple_Check(argv)) {
4801 argc = PyTuple_Size(argv);
4802 getitem = PyTuple_GetItem;
4803 }
4804 else {
4805 PyErr_SetString(PyExc_TypeError,
4806 "spawnv() arg 2 must be a tuple or list");
4807 Py_DECREF(opath);
4808 return NULL;
4809 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004810
Victor Stinner8c62be82010-05-06 00:08:46 +00004811 argvlist = PyMem_NEW(char *, argc+1);
4812 if (argvlist == NULL) {
4813 Py_DECREF(opath);
4814 return PyErr_NoMemory();
4815 }
4816 for (i = 0; i < argc; i++) {
4817 if (!fsconvert_strdup((*getitem)(argv, i),
4818 &argvlist[i])) {
4819 free_string_array(argvlist, i);
4820 PyErr_SetString(
4821 PyExc_TypeError,
4822 "spawnv() arg 2 must contain only strings");
4823 Py_DECREF(opath);
4824 return NULL;
4825 }
4826 }
4827 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004828
Victor Stinner8c62be82010-05-06 00:08:46 +00004829 if (mode == _OLD_P_OVERLAY)
4830 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00004831
Victor Stinner8c62be82010-05-06 00:08:46 +00004832 Py_BEGIN_ALLOW_THREADS
4833 spawnval = _spawnv(mode, path, argvlist);
4834 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00004835
Victor Stinner8c62be82010-05-06 00:08:46 +00004836 free_string_array(argvlist, argc);
4837 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00004838
Victor Stinner8c62be82010-05-06 00:08:46 +00004839 if (spawnval == -1)
4840 return posix_error();
4841 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004842#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00004843 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004844#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004845 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004846#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00004847}
4848
4849
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004850PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004851"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004852Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004853\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004854 mode: mode of process creation\n\
4855 path: path of executable file\n\
4856 args: tuple or list of arguments\n\
4857 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004858
4859static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004860posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004861{
Victor Stinner8c62be82010-05-06 00:08:46 +00004862 PyObject *opath;
4863 char *path;
4864 PyObject *argv, *env;
4865 char **argvlist;
4866 char **envlist;
4867 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00004868 int mode;
4869 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00004870 Py_intptr_t spawnval;
4871 PyObject *(*getitem)(PyObject *, Py_ssize_t);
4872 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00004873
Victor Stinner8c62be82010-05-06 00:08:46 +00004874 /* spawnve has four arguments: (mode, path, argv, env), where
4875 argv is a list or tuple of strings and env is a dictionary
4876 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004877
Victor Stinner8c62be82010-05-06 00:08:46 +00004878 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
4879 PyUnicode_FSConverter,
4880 &opath, &argv, &env))
4881 return NULL;
4882 path = PyBytes_AsString(opath);
4883 if (PyList_Check(argv)) {
4884 argc = PyList_Size(argv);
4885 getitem = PyList_GetItem;
4886 }
4887 else if (PyTuple_Check(argv)) {
4888 argc = PyTuple_Size(argv);
4889 getitem = PyTuple_GetItem;
4890 }
4891 else {
4892 PyErr_SetString(PyExc_TypeError,
4893 "spawnve() arg 2 must be a tuple or list");
4894 goto fail_0;
4895 }
4896 if (!PyMapping_Check(env)) {
4897 PyErr_SetString(PyExc_TypeError,
4898 "spawnve() arg 3 must be a mapping object");
4899 goto fail_0;
4900 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004901
Victor Stinner8c62be82010-05-06 00:08:46 +00004902 argvlist = PyMem_NEW(char *, argc+1);
4903 if (argvlist == NULL) {
4904 PyErr_NoMemory();
4905 goto fail_0;
4906 }
4907 for (i = 0; i < argc; i++) {
4908 if (!fsconvert_strdup((*getitem)(argv, i),
4909 &argvlist[i]))
4910 {
4911 lastarg = i;
4912 goto fail_1;
4913 }
4914 }
4915 lastarg = argc;
4916 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004917
Victor Stinner8c62be82010-05-06 00:08:46 +00004918 envlist = parse_envlist(env, &envc);
4919 if (envlist == NULL)
4920 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00004921
Victor Stinner8c62be82010-05-06 00:08:46 +00004922 if (mode == _OLD_P_OVERLAY)
4923 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00004924
Victor Stinner8c62be82010-05-06 00:08:46 +00004925 Py_BEGIN_ALLOW_THREADS
4926 spawnval = _spawnve(mode, path, argvlist, envlist);
4927 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00004928
Victor Stinner8c62be82010-05-06 00:08:46 +00004929 if (spawnval == -1)
4930 (void) posix_error();
4931 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004932#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00004933 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004934#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004935 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004936#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00004937
Victor Stinner8c62be82010-05-06 00:08:46 +00004938 while (--envc >= 0)
4939 PyMem_DEL(envlist[envc]);
4940 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004941 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00004942 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004943 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004944 Py_DECREF(opath);
4945 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00004946}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004947
Guido van Rossuma1065681999-01-25 23:20:23 +00004948#endif /* HAVE_SPAWNV */
4949
4950
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004951#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004952PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004953"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004954Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
4955\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004956Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004957
4958static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004959posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004960{
Victor Stinner8c62be82010-05-06 00:08:46 +00004961 pid_t pid;
4962 int result = 0;
4963 _PyImport_AcquireLock();
4964 pid = fork1();
4965 if (pid == 0) {
4966 /* child: this clobbers and resets the import lock. */
4967 PyOS_AfterFork();
4968 } else {
4969 /* parent: release the import lock. */
4970 result = _PyImport_ReleaseLock();
4971 }
4972 if (pid == -1)
4973 return posix_error();
4974 if (result < 0) {
4975 /* Don't clobber the OSError if the fork failed. */
4976 PyErr_SetString(PyExc_RuntimeError,
4977 "not holding the import lock");
4978 return NULL;
4979 }
4980 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004981}
4982#endif
4983
4984
Guido van Rossumad0ee831995-03-01 10:34:45 +00004985#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004986PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004987"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004988Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004989Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004990
Barry Warsaw53699e91996-12-10 23:23:01 +00004991static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004992posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004993{
Victor Stinner8c62be82010-05-06 00:08:46 +00004994 pid_t pid;
4995 int result = 0;
4996 _PyImport_AcquireLock();
4997 pid = fork();
4998 if (pid == 0) {
4999 /* child: this clobbers and resets the import lock. */
5000 PyOS_AfterFork();
5001 } else {
5002 /* parent: release the import lock. */
5003 result = _PyImport_ReleaseLock();
5004 }
5005 if (pid == -1)
5006 return posix_error();
5007 if (result < 0) {
5008 /* Don't clobber the OSError if the fork failed. */
5009 PyErr_SetString(PyExc_RuntimeError,
5010 "not holding the import lock");
5011 return NULL;
5012 }
5013 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005014}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005015#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005016
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005017#ifdef HAVE_SCHED_H
5018
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005019#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5020
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005021PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5022"sched_get_priority_max(policy)\n\n\
5023Get the maximum scheduling priority for *policy*.");
5024
5025static PyObject *
5026posix_sched_get_priority_max(PyObject *self, PyObject *args)
5027{
5028 int policy, max;
5029
5030 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5031 return NULL;
5032 max = sched_get_priority_max(policy);
5033 if (max < 0)
5034 return posix_error();
5035 return PyLong_FromLong(max);
5036}
5037
5038PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5039"sched_get_priority_min(policy)\n\n\
5040Get the minimum scheduling priority for *policy*.");
5041
5042static PyObject *
5043posix_sched_get_priority_min(PyObject *self, PyObject *args)
5044{
5045 int policy, min;
5046
5047 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5048 return NULL;
5049 min = sched_get_priority_min(policy);
5050 if (min < 0)
5051 return posix_error();
5052 return PyLong_FromLong(min);
5053}
5054
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005055#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5056
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005057#ifdef HAVE_SCHED_SETSCHEDULER
5058
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005059PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5060"sched_getscheduler(pid)\n\n\
5061Get the scheduling policy for the process with a PID of *pid*.\n\
5062Passing a PID of 0 returns the scheduling policy for the calling process.");
5063
5064static PyObject *
5065posix_sched_getscheduler(PyObject *self, PyObject *args)
5066{
5067 pid_t pid;
5068 int policy;
5069
5070 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5071 return NULL;
5072 policy = sched_getscheduler(pid);
5073 if (policy < 0)
5074 return posix_error();
5075 return PyLong_FromLong(policy);
5076}
5077
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005078#endif
5079
5080#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5081
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005082static PyObject *
5083sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5084{
5085 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005086 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005087
5088 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5089 return NULL;
5090 res = PyStructSequence_New(type);
5091 if (!res)
5092 return NULL;
5093 Py_INCREF(priority);
5094 PyStructSequence_SET_ITEM(res, 0, priority);
5095 return res;
5096}
5097
5098PyDoc_STRVAR(sched_param__doc__,
5099"sched_param(sched_priority): A scheduling parameter.\n\n\
5100Current has only one field: sched_priority");
5101
5102static PyStructSequence_Field sched_param_fields[] = {
5103 {"sched_priority", "the scheduling priority"},
5104 {0}
5105};
5106
5107static PyStructSequence_Desc sched_param_desc = {
5108 "sched_param", /* name */
5109 sched_param__doc__, /* doc */
5110 sched_param_fields,
5111 1
5112};
5113
5114static int
5115convert_sched_param(PyObject *param, struct sched_param *res)
5116{
5117 long priority;
5118
5119 if (Py_TYPE(param) != &SchedParamType) {
5120 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5121 return 0;
5122 }
5123 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5124 if (priority == -1 && PyErr_Occurred())
5125 return 0;
5126 if (priority > INT_MAX || priority < INT_MIN) {
5127 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5128 return 0;
5129 }
5130 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5131 return 1;
5132}
5133
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005134#endif
5135
5136#ifdef HAVE_SCHED_SETSCHEDULER
5137
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005138PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5139"sched_setscheduler(pid, policy, param)\n\n\
5140Set the scheduling policy, *policy*, for *pid*.\n\
5141If *pid* is 0, the calling process is changed.\n\
5142*param* is an instance of sched_param.");
5143
5144static PyObject *
5145posix_sched_setscheduler(PyObject *self, PyObject *args)
5146{
5147 pid_t pid;
5148 int policy;
5149 struct sched_param param;
5150
5151 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5152 &pid, &policy, &convert_sched_param, &param))
5153 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005154
5155 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005156 ** sched_setscheduler() returns 0 in Linux, but the previous
5157 ** scheduling policy under Solaris/Illumos, and others.
5158 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005159 */
5160 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005161 return posix_error();
5162 Py_RETURN_NONE;
5163}
5164
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005165#endif
5166
5167#ifdef HAVE_SCHED_SETPARAM
5168
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005169PyDoc_STRVAR(posix_sched_getparam__doc__,
5170"sched_getparam(pid) -> sched_param\n\n\
5171Returns scheduling parameters for the process with *pid* as an instance of the\n\
5172sched_param class. A PID of 0 means the calling process.");
5173
5174static PyObject *
5175posix_sched_getparam(PyObject *self, PyObject *args)
5176{
5177 pid_t pid;
5178 struct sched_param param;
5179 PyObject *res, *priority;
5180
5181 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5182 return NULL;
5183 if (sched_getparam(pid, &param))
5184 return posix_error();
5185 res = PyStructSequence_New(&SchedParamType);
5186 if (!res)
5187 return NULL;
5188 priority = PyLong_FromLong(param.sched_priority);
5189 if (!priority) {
5190 Py_DECREF(res);
5191 return NULL;
5192 }
5193 PyStructSequence_SET_ITEM(res, 0, priority);
5194 return res;
5195}
5196
5197PyDoc_STRVAR(posix_sched_setparam__doc__,
5198"sched_setparam(pid, param)\n\n\
5199Set scheduling parameters for a process with PID *pid*.\n\
5200A PID of 0 means the calling process.");
5201
5202static PyObject *
5203posix_sched_setparam(PyObject *self, PyObject *args)
5204{
5205 pid_t pid;
5206 struct sched_param param;
5207
5208 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5209 &pid, &convert_sched_param, &param))
5210 return NULL;
5211 if (sched_setparam(pid, &param))
5212 return posix_error();
5213 Py_RETURN_NONE;
5214}
5215
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005216#endif
5217
5218#ifdef HAVE_SCHED_RR_GET_INTERVAL
5219
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005220PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5221"sched_rr_get_interval(pid) -> float\n\n\
5222Return the round-robin quantum for the process with PID *pid* in seconds.");
5223
5224static PyObject *
5225posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5226{
5227 pid_t pid;
5228 struct timespec interval;
5229
5230 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5231 return NULL;
5232 if (sched_rr_get_interval(pid, &interval))
5233 return posix_error();
5234 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5235}
5236
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005237#endif
5238
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005239PyDoc_STRVAR(posix_sched_yield__doc__,
5240"sched_yield()\n\n\
5241Voluntarily relinquish the CPU.");
5242
5243static PyObject *
5244posix_sched_yield(PyObject *self, PyObject *noargs)
5245{
5246 if (sched_yield())
5247 return posix_error();
5248 Py_RETURN_NONE;
5249}
5250
Benjamin Peterson2740af82011-08-02 17:41:34 -05005251#ifdef HAVE_SCHED_SETAFFINITY
5252
Antoine Pitrou84869872012-08-04 16:16:35 +02005253/* The minimum number of CPUs allocated in a cpu_set_t */
5254static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005255
5256PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5257"sched_setaffinity(pid, cpu_set)\n\n\
5258Set the affinity of the process with PID *pid* to *cpu_set*.");
5259
5260static PyObject *
5261posix_sched_setaffinity(PyObject *self, PyObject *args)
5262{
5263 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005264 int ncpus;
5265 size_t setsize;
5266 cpu_set_t *mask = NULL;
5267 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005268
Antoine Pitrou84869872012-08-04 16:16:35 +02005269 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5270 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005271 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005272
5273 iterator = PyObject_GetIter(iterable);
5274 if (iterator == NULL)
5275 return NULL;
5276
5277 ncpus = NCPUS_START;
5278 setsize = CPU_ALLOC_SIZE(ncpus);
5279 mask = CPU_ALLOC(ncpus);
5280 if (mask == NULL) {
5281 PyErr_NoMemory();
5282 goto error;
5283 }
5284 CPU_ZERO_S(setsize, mask);
5285
5286 while ((item = PyIter_Next(iterator))) {
5287 long cpu;
5288 if (!PyLong_Check(item)) {
5289 PyErr_Format(PyExc_TypeError,
5290 "expected an iterator of ints, "
5291 "but iterator yielded %R",
5292 Py_TYPE(item));
5293 Py_DECREF(item);
5294 goto error;
5295 }
5296 cpu = PyLong_AsLong(item);
5297 Py_DECREF(item);
5298 if (cpu < 0) {
5299 if (!PyErr_Occurred())
5300 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5301 goto error;
5302 }
5303 if (cpu > INT_MAX - 1) {
5304 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5305 goto error;
5306 }
5307 if (cpu >= ncpus) {
5308 /* Grow CPU mask to fit the CPU number */
5309 int newncpus = ncpus;
5310 cpu_set_t *newmask;
5311 size_t newsetsize;
5312 while (newncpus <= cpu) {
5313 if (newncpus > INT_MAX / 2)
5314 newncpus = cpu + 1;
5315 else
5316 newncpus = newncpus * 2;
5317 }
5318 newmask = CPU_ALLOC(newncpus);
5319 if (newmask == NULL) {
5320 PyErr_NoMemory();
5321 goto error;
5322 }
5323 newsetsize = CPU_ALLOC_SIZE(newncpus);
5324 CPU_ZERO_S(newsetsize, newmask);
5325 memcpy(newmask, mask, setsize);
5326 CPU_FREE(mask);
5327 setsize = newsetsize;
5328 mask = newmask;
5329 ncpus = newncpus;
5330 }
5331 CPU_SET_S(cpu, setsize, mask);
5332 }
5333 Py_CLEAR(iterator);
5334
5335 if (sched_setaffinity(pid, setsize, mask)) {
5336 posix_error();
5337 goto error;
5338 }
5339 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005340 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005341
5342error:
5343 if (mask)
5344 CPU_FREE(mask);
5345 Py_XDECREF(iterator);
5346 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005347}
5348
5349PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5350"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5351Return the affinity of the process with PID *pid*.\n\
5352The returned cpu_set will be of size *ncpus*.");
5353
5354static PyObject *
5355posix_sched_getaffinity(PyObject *self, PyObject *args)
5356{
5357 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005358 int cpu, ncpus, count;
5359 size_t setsize;
5360 cpu_set_t *mask = NULL;
5361 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005362
Antoine Pitrou84869872012-08-04 16:16:35 +02005363 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
5364 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005365 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005366
5367 ncpus = NCPUS_START;
5368 while (1) {
5369 setsize = CPU_ALLOC_SIZE(ncpus);
5370 mask = CPU_ALLOC(ncpus);
5371 if (mask == NULL)
5372 return PyErr_NoMemory();
5373 if (sched_getaffinity(pid, setsize, mask) == 0)
5374 break;
5375 CPU_FREE(mask);
5376 if (errno != EINVAL)
5377 return posix_error();
5378 if (ncpus > INT_MAX / 2) {
5379 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5380 "a large enough CPU set");
5381 return NULL;
5382 }
5383 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005384 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005385
5386 res = PySet_New(NULL);
5387 if (res == NULL)
5388 goto error;
5389 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5390 if (CPU_ISSET_S(cpu, setsize, mask)) {
5391 PyObject *cpu_num = PyLong_FromLong(cpu);
5392 --count;
5393 if (cpu_num == NULL)
5394 goto error;
5395 if (PySet_Add(res, cpu_num)) {
5396 Py_DECREF(cpu_num);
5397 goto error;
5398 }
5399 Py_DECREF(cpu_num);
5400 }
5401 }
5402 CPU_FREE(mask);
5403 return res;
5404
5405error:
5406 if (mask)
5407 CPU_FREE(mask);
5408 Py_XDECREF(res);
5409 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005410}
5411
Benjamin Peterson2740af82011-08-02 17:41:34 -05005412#endif /* HAVE_SCHED_SETAFFINITY */
5413
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005414#endif /* HAVE_SCHED_H */
5415
Neal Norwitzb59798b2003-03-21 01:43:31 +00005416/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005417/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5418#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005419#define DEV_PTY_FILE "/dev/ptc"
5420#define HAVE_DEV_PTMX
5421#else
5422#define DEV_PTY_FILE "/dev/ptmx"
5423#endif
5424
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005425#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005426#ifdef HAVE_PTY_H
5427#include <pty.h>
5428#else
5429#ifdef HAVE_LIBUTIL_H
5430#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005431#else
5432#ifdef HAVE_UTIL_H
5433#include <util.h>
5434#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005435#endif /* HAVE_LIBUTIL_H */
5436#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005437#ifdef HAVE_STROPTS_H
5438#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005439#endif
5440#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005441
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005442#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005443PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005444"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005445Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005446
5447static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005448posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005449{
Victor Stinner8c62be82010-05-06 00:08:46 +00005450 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005451#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005452 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005453#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005454#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005455 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005456#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005457 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005458#endif
5459#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005460
Thomas Wouters70c21a12000-07-14 14:28:33 +00005461#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005462 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
5463 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005464#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005465 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5466 if (slave_name == NULL)
5467 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00005468
Victor Stinner8c62be82010-05-06 00:08:46 +00005469 slave_fd = open(slave_name, O_RDWR);
5470 if (slave_fd < 0)
5471 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005472#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005473 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
5474 if (master_fd < 0)
5475 return posix_error();
5476 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
5477 /* change permission of slave */
5478 if (grantpt(master_fd) < 0) {
5479 PyOS_setsig(SIGCHLD, sig_saved);
5480 return posix_error();
5481 }
5482 /* unlock slave */
5483 if (unlockpt(master_fd) < 0) {
5484 PyOS_setsig(SIGCHLD, sig_saved);
5485 return posix_error();
5486 }
5487 PyOS_setsig(SIGCHLD, sig_saved);
5488 slave_name = ptsname(master_fd); /* get name of slave */
5489 if (slave_name == NULL)
5490 return posix_error();
5491 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
5492 if (slave_fd < 0)
5493 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005494#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005495 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5496 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005497#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005498 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005499#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005500#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005501#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005502
Victor Stinner8c62be82010-05-06 00:08:46 +00005503 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005504
Fred Drake8cef4cf2000-06-28 16:40:38 +00005505}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005506#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005507
5508#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005509PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005510"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00005511Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
5512Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005513To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005514
5515static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005516posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005517{
Victor Stinner8c62be82010-05-06 00:08:46 +00005518 int master_fd = -1, result = 0;
5519 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005520
Victor Stinner8c62be82010-05-06 00:08:46 +00005521 _PyImport_AcquireLock();
5522 pid = forkpty(&master_fd, NULL, NULL, NULL);
5523 if (pid == 0) {
5524 /* child: this clobbers and resets the import lock. */
5525 PyOS_AfterFork();
5526 } else {
5527 /* parent: release the import lock. */
5528 result = _PyImport_ReleaseLock();
5529 }
5530 if (pid == -1)
5531 return posix_error();
5532 if (result < 0) {
5533 /* Don't clobber the OSError if the fork failed. */
5534 PyErr_SetString(PyExc_RuntimeError,
5535 "not holding the import lock");
5536 return NULL;
5537 }
5538 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005539}
5540#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005541
Ross Lagerwall7807c352011-03-17 20:20:30 +02005542
Guido van Rossumad0ee831995-03-01 10:34:45 +00005543#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005544PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005545"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005546Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005547
Barry Warsaw53699e91996-12-10 23:23:01 +00005548static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005549posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005550{
Victor Stinner8c62be82010-05-06 00:08:46 +00005551 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005552}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005553#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005554
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005555
Guido van Rossumad0ee831995-03-01 10:34:45 +00005556#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005557PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005558"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005559Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005560
Barry Warsaw53699e91996-12-10 23:23:01 +00005561static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005562posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005563{
Victor Stinner8c62be82010-05-06 00:08:46 +00005564 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005565}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005566#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005567
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005568
Guido van Rossumad0ee831995-03-01 10:34:45 +00005569#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005570PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005571"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005572Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005573
Barry Warsaw53699e91996-12-10 23:23:01 +00005574static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005575posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005576{
Victor Stinner8c62be82010-05-06 00:08:46 +00005577 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005578}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005579#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005580
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005581
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005582PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005583"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005584Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005585
Barry Warsaw53699e91996-12-10 23:23:01 +00005586static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005587posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005588{
Victor Stinner8c62be82010-05-06 00:08:46 +00005589 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005590}
5591
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005592#ifdef HAVE_GETGROUPLIST
5593PyDoc_STRVAR(posix_getgrouplist__doc__,
5594"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5595Returns a list of groups to which a user belongs.\n\n\
5596 user: username to lookup\n\
5597 group: base group id of the user");
5598
5599static PyObject *
5600posix_getgrouplist(PyObject *self, PyObject *args)
5601{
5602#ifdef NGROUPS_MAX
5603#define MAX_GROUPS NGROUPS_MAX
5604#else
5605 /* defined to be 16 on Solaris7, so this should be a small number */
5606#define MAX_GROUPS 64
5607#endif
5608
5609 const char *user;
5610 int i, ngroups;
5611 PyObject *list;
5612#ifdef __APPLE__
5613 int *groups, basegid;
5614#else
5615 gid_t *groups, basegid;
5616#endif
5617 ngroups = MAX_GROUPS;
5618
5619 if (!PyArg_ParseTuple(args, "si", &user, &basegid))
5620 return NULL;
5621
5622#ifdef __APPLE__
5623 groups = PyMem_Malloc(ngroups * sizeof(int));
5624#else
5625 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
5626#endif
5627 if (groups == NULL)
5628 return PyErr_NoMemory();
5629
5630 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
5631 PyMem_Del(groups);
5632 return posix_error();
5633 }
5634
5635 list = PyList_New(ngroups);
5636 if (list == NULL) {
5637 PyMem_Del(groups);
5638 return NULL;
5639 }
5640
5641 for (i = 0; i < ngroups; i++) {
5642 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
5643 if (o == NULL) {
5644 Py_DECREF(list);
5645 PyMem_Del(groups);
5646 return NULL;
5647 }
5648 PyList_SET_ITEM(list, i, o);
5649 }
5650
5651 PyMem_Del(groups);
5652
5653 return list;
5654}
5655#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005656
Fred Drakec9680921999-12-13 16:37:25 +00005657#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005658PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005659"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005660Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00005661
5662static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005663posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00005664{
5665 PyObject *result = NULL;
5666
Fred Drakec9680921999-12-13 16:37:25 +00005667#ifdef NGROUPS_MAX
5668#define MAX_GROUPS NGROUPS_MAX
5669#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005670 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00005671#define MAX_GROUPS 64
5672#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005673 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005674
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005675 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005676 * This is a helper variable to store the intermediate result when
5677 * that happens.
5678 *
5679 * To keep the code readable the OSX behaviour is unconditional,
5680 * according to the POSIX spec this should be safe on all unix-y
5681 * systems.
5682 */
5683 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005684 int n;
Fred Drakec9680921999-12-13 16:37:25 +00005685
Victor Stinner8c62be82010-05-06 00:08:46 +00005686 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005687 if (n < 0) {
5688 if (errno == EINVAL) {
5689 n = getgroups(0, NULL);
5690 if (n == -1) {
5691 return posix_error();
5692 }
5693 if (n == 0) {
5694 /* Avoid malloc(0) */
5695 alt_grouplist = grouplist;
5696 } else {
5697 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
5698 if (alt_grouplist == NULL) {
5699 errno = EINVAL;
5700 return posix_error();
5701 }
5702 n = getgroups(n, alt_grouplist);
5703 if (n == -1) {
5704 PyMem_Free(alt_grouplist);
5705 return posix_error();
5706 }
5707 }
5708 } else {
5709 return posix_error();
5710 }
5711 }
5712 result = PyList_New(n);
5713 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005714 int i;
5715 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005716 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00005717 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00005718 Py_DECREF(result);
5719 result = NULL;
5720 break;
Fred Drakec9680921999-12-13 16:37:25 +00005721 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005722 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00005723 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005724 }
5725
5726 if (alt_grouplist != grouplist) {
5727 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005728 }
Neal Norwitze241ce82003-02-17 18:17:05 +00005729
Fred Drakec9680921999-12-13 16:37:25 +00005730 return result;
5731}
5732#endif
5733
Antoine Pitroub7572f02009-12-02 20:46:48 +00005734#ifdef HAVE_INITGROUPS
5735PyDoc_STRVAR(posix_initgroups__doc__,
5736"initgroups(username, gid) -> None\n\n\
5737Call the system initgroups() to initialize the group access list with all of\n\
5738the groups of which the specified username is a member, plus the specified\n\
5739group id.");
5740
5741static PyObject *
5742posix_initgroups(PyObject *self, PyObject *args)
5743{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005744 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00005745 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005746 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00005747 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005748
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005749 if (!PyArg_ParseTuple(args, "O&l:initgroups",
5750 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00005751 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005752 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005753
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005754 res = initgroups(username, (gid_t) gid);
5755 Py_DECREF(oname);
5756 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00005757 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005758
Victor Stinner8c62be82010-05-06 00:08:46 +00005759 Py_INCREF(Py_None);
5760 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005761}
5762#endif
5763
Martin v. Löwis606edc12002-06-13 21:09:11 +00005764#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005765PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005766"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005767Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00005768
5769static PyObject *
5770posix_getpgid(PyObject *self, PyObject *args)
5771{
Victor Stinner8c62be82010-05-06 00:08:46 +00005772 pid_t pid, pgid;
5773 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
5774 return NULL;
5775 pgid = getpgid(pid);
5776 if (pgid < 0)
5777 return posix_error();
5778 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00005779}
5780#endif /* HAVE_GETPGID */
5781
5782
Guido van Rossumb6775db1994-08-01 11:34:53 +00005783#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005784PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005785"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005786Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005787
Barry Warsaw53699e91996-12-10 23:23:01 +00005788static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005789posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00005790{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005791#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005792 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005793#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005794 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005795#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00005796}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005797#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00005798
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005799
Guido van Rossumb6775db1994-08-01 11:34:53 +00005800#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005801PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005802"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00005803Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005804
Barry Warsaw53699e91996-12-10 23:23:01 +00005805static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005806posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005807{
Guido van Rossum64933891994-10-20 21:56:42 +00005808#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005809 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005810#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005811 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005812#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005813 return posix_error();
5814 Py_INCREF(Py_None);
5815 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005816}
5817
Guido van Rossumb6775db1994-08-01 11:34:53 +00005818#endif /* HAVE_SETPGRP */
5819
Guido van Rossumad0ee831995-03-01 10:34:45 +00005820#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005821
5822#ifdef MS_WINDOWS
5823#include <tlhelp32.h>
5824
5825static PyObject*
5826win32_getppid()
5827{
5828 HANDLE snapshot;
5829 pid_t mypid;
5830 PyObject* result = NULL;
5831 BOOL have_record;
5832 PROCESSENTRY32 pe;
5833
5834 mypid = getpid(); /* This function never fails */
5835
5836 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
5837 if (snapshot == INVALID_HANDLE_VALUE)
5838 return PyErr_SetFromWindowsErr(GetLastError());
5839
5840 pe.dwSize = sizeof(pe);
5841 have_record = Process32First(snapshot, &pe);
5842 while (have_record) {
5843 if (mypid == (pid_t)pe.th32ProcessID) {
5844 /* We could cache the ulong value in a static variable. */
5845 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
5846 break;
5847 }
5848
5849 have_record = Process32Next(snapshot, &pe);
5850 }
5851
5852 /* If our loop exits and our pid was not found (result will be NULL)
5853 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
5854 * error anyway, so let's raise it. */
5855 if (!result)
5856 result = PyErr_SetFromWindowsErr(GetLastError());
5857
5858 CloseHandle(snapshot);
5859
5860 return result;
5861}
5862#endif /*MS_WINDOWS*/
5863
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005864PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005865"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005866Return the parent's process id. If the parent process has already exited,\n\
5867Windows machines will still return its id; others systems will return the id\n\
5868of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005869
Barry Warsaw53699e91996-12-10 23:23:01 +00005870static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005871posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005872{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005873#ifdef MS_WINDOWS
5874 return win32_getppid();
5875#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005876 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00005877#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005878}
5879#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005880
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005881
Fred Drake12c6e2d1999-12-14 21:25:03 +00005882#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005883PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005884"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005885Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00005886
5887static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005888posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005889{
Victor Stinner8c62be82010-05-06 00:08:46 +00005890 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005891#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005892 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02005893 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005894
5895 if (GetUserNameW(user_name, &num_chars)) {
5896 /* num_chars is the number of unicode chars plus null terminator */
5897 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005898 }
5899 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005900 result = PyErr_SetFromWindowsErr(GetLastError());
5901#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005902 char *name;
5903 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005904
Victor Stinner8c62be82010-05-06 00:08:46 +00005905 errno = 0;
5906 name = getlogin();
5907 if (name == NULL) {
5908 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00005909 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00005910 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00005911 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00005912 }
5913 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00005914 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00005915 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005916#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00005917 return result;
5918}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005919#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005920
Guido van Rossumad0ee831995-03-01 10:34:45 +00005921#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005922PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005923"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005924Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005925
Barry Warsaw53699e91996-12-10 23:23:01 +00005926static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005927posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005928{
Victor Stinner8c62be82010-05-06 00:08:46 +00005929 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005930}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005931#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005932
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005933
Guido van Rossumad0ee831995-03-01 10:34:45 +00005934#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005935PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005936"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005937Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005938
Barry Warsaw53699e91996-12-10 23:23:01 +00005939static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005940posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005941{
Victor Stinner8c62be82010-05-06 00:08:46 +00005942 pid_t pid;
5943 int sig;
5944 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
5945 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005946 if (kill(pid, sig) == -1)
5947 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005948 Py_INCREF(Py_None);
5949 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00005950}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005951#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005952
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005953#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005954PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005955"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005956Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005957
5958static PyObject *
5959posix_killpg(PyObject *self, PyObject *args)
5960{
Victor Stinner8c62be82010-05-06 00:08:46 +00005961 int sig;
5962 pid_t pgid;
5963 /* XXX some man pages make the `pgid` parameter an int, others
5964 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
5965 take the same type. Moreover, pid_t is always at least as wide as
5966 int (else compilation of this module fails), which is safe. */
5967 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
5968 return NULL;
5969 if (killpg(pgid, sig) == -1)
5970 return posix_error();
5971 Py_INCREF(Py_None);
5972 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005973}
5974#endif
5975
Brian Curtineb24d742010-04-12 17:16:38 +00005976#ifdef MS_WINDOWS
5977PyDoc_STRVAR(win32_kill__doc__,
5978"kill(pid, sig)\n\n\
5979Kill a process with a signal.");
5980
5981static PyObject *
5982win32_kill(PyObject *self, PyObject *args)
5983{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00005984 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00005985 DWORD pid, sig, err;
5986 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00005987
Victor Stinner8c62be82010-05-06 00:08:46 +00005988 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
5989 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00005990
Victor Stinner8c62be82010-05-06 00:08:46 +00005991 /* Console processes which share a common console can be sent CTRL+C or
5992 CTRL+BREAK events, provided they handle said events. */
5993 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
5994 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
5995 err = GetLastError();
5996 PyErr_SetFromWindowsErr(err);
5997 }
5998 else
5999 Py_RETURN_NONE;
6000 }
Brian Curtineb24d742010-04-12 17:16:38 +00006001
Victor Stinner8c62be82010-05-06 00:08:46 +00006002 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6003 attempt to open and terminate the process. */
6004 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
6005 if (handle == NULL) {
6006 err = GetLastError();
6007 return PyErr_SetFromWindowsErr(err);
6008 }
Brian Curtineb24d742010-04-12 17:16:38 +00006009
Victor Stinner8c62be82010-05-06 00:08:46 +00006010 if (TerminateProcess(handle, sig) == 0) {
6011 err = GetLastError();
6012 result = PyErr_SetFromWindowsErr(err);
6013 } else {
6014 Py_INCREF(Py_None);
6015 result = Py_None;
6016 }
Brian Curtineb24d742010-04-12 17:16:38 +00006017
Victor Stinner8c62be82010-05-06 00:08:46 +00006018 CloseHandle(handle);
6019 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006020}
6021#endif /* MS_WINDOWS */
6022
Guido van Rossumc0125471996-06-28 18:55:32 +00006023#ifdef HAVE_PLOCK
6024
6025#ifdef HAVE_SYS_LOCK_H
6026#include <sys/lock.h>
6027#endif
6028
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006029PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006030"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006031Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006032
Barry Warsaw53699e91996-12-10 23:23:01 +00006033static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006034posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006035{
Victor Stinner8c62be82010-05-06 00:08:46 +00006036 int op;
6037 if (!PyArg_ParseTuple(args, "i:plock", &op))
6038 return NULL;
6039 if (plock(op) == -1)
6040 return posix_error();
6041 Py_INCREF(Py_None);
6042 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006043}
6044#endif
6045
Guido van Rossumb6775db1994-08-01 11:34:53 +00006046#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006047PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006048"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006049Set the current process's user id.");
6050
Barry Warsaw53699e91996-12-10 23:23:01 +00006051static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006052posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006053{
Victor Stinner8c62be82010-05-06 00:08:46 +00006054 long uid_arg;
6055 uid_t uid;
6056 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
6057 return NULL;
6058 uid = uid_arg;
6059 if (uid != uid_arg) {
6060 PyErr_SetString(PyExc_OverflowError, "user id too big");
6061 return NULL;
6062 }
6063 if (setuid(uid) < 0)
6064 return posix_error();
6065 Py_INCREF(Py_None);
6066 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006067}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006068#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006069
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006070
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006071#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006072PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006073"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006074Set the current process's effective user id.");
6075
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006076static PyObject *
6077posix_seteuid (PyObject *self, PyObject *args)
6078{
Victor Stinner8c62be82010-05-06 00:08:46 +00006079 long euid_arg;
6080 uid_t euid;
6081 if (!PyArg_ParseTuple(args, "l", &euid_arg))
6082 return NULL;
6083 euid = euid_arg;
6084 if (euid != euid_arg) {
6085 PyErr_SetString(PyExc_OverflowError, "user id too big");
6086 return NULL;
6087 }
6088 if (seteuid(euid) < 0) {
6089 return posix_error();
6090 } else {
6091 Py_INCREF(Py_None);
6092 return Py_None;
6093 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006094}
6095#endif /* HAVE_SETEUID */
6096
6097#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006098PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006099"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006100Set the current process's effective group id.");
6101
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006102static PyObject *
6103posix_setegid (PyObject *self, PyObject *args)
6104{
Victor Stinner8c62be82010-05-06 00:08:46 +00006105 long egid_arg;
6106 gid_t egid;
6107 if (!PyArg_ParseTuple(args, "l", &egid_arg))
6108 return NULL;
6109 egid = egid_arg;
6110 if (egid != egid_arg) {
6111 PyErr_SetString(PyExc_OverflowError, "group id too big");
6112 return NULL;
6113 }
6114 if (setegid(egid) < 0) {
6115 return posix_error();
6116 } else {
6117 Py_INCREF(Py_None);
6118 return Py_None;
6119 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006120}
6121#endif /* HAVE_SETEGID */
6122
6123#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006124PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006125"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006126Set the current process's real and effective user ids.");
6127
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006128static PyObject *
6129posix_setreuid (PyObject *self, PyObject *args)
6130{
Victor Stinner8c62be82010-05-06 00:08:46 +00006131 long ruid_arg, euid_arg;
6132 uid_t ruid, euid;
6133 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
6134 return NULL;
6135 if (ruid_arg == -1)
6136 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
6137 else
6138 ruid = ruid_arg; /* otherwise, assign from our long */
6139 if (euid_arg == -1)
6140 euid = (uid_t)-1;
6141 else
6142 euid = euid_arg;
6143 if ((euid_arg != -1 && euid != euid_arg) ||
6144 (ruid_arg != -1 && ruid != ruid_arg)) {
6145 PyErr_SetString(PyExc_OverflowError, "user id too big");
6146 return NULL;
6147 }
6148 if (setreuid(ruid, euid) < 0) {
6149 return posix_error();
6150 } else {
6151 Py_INCREF(Py_None);
6152 return Py_None;
6153 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006154}
6155#endif /* HAVE_SETREUID */
6156
6157#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006158PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006159"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006160Set the current process's real and effective group ids.");
6161
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006162static PyObject *
6163posix_setregid (PyObject *self, PyObject *args)
6164{
Victor Stinner8c62be82010-05-06 00:08:46 +00006165 long rgid_arg, egid_arg;
6166 gid_t rgid, egid;
6167 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
6168 return NULL;
6169 if (rgid_arg == -1)
6170 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
6171 else
6172 rgid = rgid_arg; /* otherwise, assign from our long */
6173 if (egid_arg == -1)
6174 egid = (gid_t)-1;
6175 else
6176 egid = egid_arg;
6177 if ((egid_arg != -1 && egid != egid_arg) ||
6178 (rgid_arg != -1 && rgid != rgid_arg)) {
6179 PyErr_SetString(PyExc_OverflowError, "group id too big");
6180 return NULL;
6181 }
6182 if (setregid(rgid, egid) < 0) {
6183 return posix_error();
6184 } else {
6185 Py_INCREF(Py_None);
6186 return Py_None;
6187 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006188}
6189#endif /* HAVE_SETREGID */
6190
Guido van Rossumb6775db1994-08-01 11:34:53 +00006191#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006192PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006193"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006194Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006195
Barry Warsaw53699e91996-12-10 23:23:01 +00006196static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006197posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006198{
Victor Stinner8c62be82010-05-06 00:08:46 +00006199 long gid_arg;
6200 gid_t gid;
6201 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
6202 return NULL;
6203 gid = gid_arg;
6204 if (gid != gid_arg) {
6205 PyErr_SetString(PyExc_OverflowError, "group id too big");
6206 return NULL;
6207 }
6208 if (setgid(gid) < 0)
6209 return posix_error();
6210 Py_INCREF(Py_None);
6211 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006212}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006213#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006214
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006215#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006216PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006217"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006218Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006219
6220static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006221posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006222{
Victor Stinner8c62be82010-05-06 00:08:46 +00006223 int i, len;
6224 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006225
Victor Stinner8c62be82010-05-06 00:08:46 +00006226 if (!PySequence_Check(groups)) {
6227 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6228 return NULL;
6229 }
6230 len = PySequence_Size(groups);
6231 if (len > MAX_GROUPS) {
6232 PyErr_SetString(PyExc_ValueError, "too many groups");
6233 return NULL;
6234 }
6235 for(i = 0; i < len; i++) {
6236 PyObject *elem;
6237 elem = PySequence_GetItem(groups, i);
6238 if (!elem)
6239 return NULL;
6240 if (!PyLong_Check(elem)) {
6241 PyErr_SetString(PyExc_TypeError,
6242 "groups must be integers");
6243 Py_DECREF(elem);
6244 return NULL;
6245 } else {
6246 unsigned long x = PyLong_AsUnsignedLong(elem);
6247 if (PyErr_Occurred()) {
6248 PyErr_SetString(PyExc_TypeError,
6249 "group id too big");
6250 Py_DECREF(elem);
6251 return NULL;
6252 }
6253 grouplist[i] = x;
6254 /* read back the value to see if it fitted in gid_t */
6255 if (grouplist[i] != x) {
6256 PyErr_SetString(PyExc_TypeError,
6257 "group id too big");
6258 Py_DECREF(elem);
6259 return NULL;
6260 }
6261 }
6262 Py_DECREF(elem);
6263 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006264
Victor Stinner8c62be82010-05-06 00:08:46 +00006265 if (setgroups(len, grouplist) < 0)
6266 return posix_error();
6267 Py_INCREF(Py_None);
6268 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006269}
6270#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006271
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006272#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6273static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006274wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006275{
Victor Stinner8c62be82010-05-06 00:08:46 +00006276 PyObject *result;
6277 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006278 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006279
Victor Stinner8c62be82010-05-06 00:08:46 +00006280 if (pid == -1)
6281 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006282
Victor Stinner8c62be82010-05-06 00:08:46 +00006283 if (struct_rusage == NULL) {
6284 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6285 if (m == NULL)
6286 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006287 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006288 Py_DECREF(m);
6289 if (struct_rusage == NULL)
6290 return NULL;
6291 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006292
Victor Stinner8c62be82010-05-06 00:08:46 +00006293 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6294 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6295 if (!result)
6296 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006297
6298#ifndef doubletime
6299#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6300#endif
6301
Victor Stinner8c62be82010-05-06 00:08:46 +00006302 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006303 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006304 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006305 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006306#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006307 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6308 SET_INT(result, 2, ru->ru_maxrss);
6309 SET_INT(result, 3, ru->ru_ixrss);
6310 SET_INT(result, 4, ru->ru_idrss);
6311 SET_INT(result, 5, ru->ru_isrss);
6312 SET_INT(result, 6, ru->ru_minflt);
6313 SET_INT(result, 7, ru->ru_majflt);
6314 SET_INT(result, 8, ru->ru_nswap);
6315 SET_INT(result, 9, ru->ru_inblock);
6316 SET_INT(result, 10, ru->ru_oublock);
6317 SET_INT(result, 11, ru->ru_msgsnd);
6318 SET_INT(result, 12, ru->ru_msgrcv);
6319 SET_INT(result, 13, ru->ru_nsignals);
6320 SET_INT(result, 14, ru->ru_nvcsw);
6321 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006322#undef SET_INT
6323
Victor Stinner8c62be82010-05-06 00:08:46 +00006324 if (PyErr_Occurred()) {
6325 Py_DECREF(result);
6326 return NULL;
6327 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006328
Victor Stinner8c62be82010-05-06 00:08:46 +00006329 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006330}
6331#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6332
6333#ifdef HAVE_WAIT3
6334PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006335"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006336Wait for completion of a child process.");
6337
6338static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006339posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006340{
Victor Stinner8c62be82010-05-06 00:08:46 +00006341 pid_t pid;
6342 int options;
6343 struct rusage ru;
6344 WAIT_TYPE status;
6345 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006346
Victor Stinner4195b5c2012-02-08 23:03:19 +01006347 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006348 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006349
Victor Stinner8c62be82010-05-06 00:08:46 +00006350 Py_BEGIN_ALLOW_THREADS
6351 pid = wait3(&status, options, &ru);
6352 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006353
Victor Stinner4195b5c2012-02-08 23:03:19 +01006354 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006355}
6356#endif /* HAVE_WAIT3 */
6357
6358#ifdef HAVE_WAIT4
6359PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006360"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006361Wait for completion of a given child process.");
6362
6363static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006364posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006365{
Victor Stinner8c62be82010-05-06 00:08:46 +00006366 pid_t pid;
6367 int options;
6368 struct rusage ru;
6369 WAIT_TYPE status;
6370 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006371
Victor Stinner4195b5c2012-02-08 23:03:19 +01006372 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006373 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006374
Victor Stinner8c62be82010-05-06 00:08:46 +00006375 Py_BEGIN_ALLOW_THREADS
6376 pid = wait4(pid, &status, options, &ru);
6377 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006378
Victor Stinner4195b5c2012-02-08 23:03:19 +01006379 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006380}
6381#endif /* HAVE_WAIT4 */
6382
Ross Lagerwall7807c352011-03-17 20:20:30 +02006383#if defined(HAVE_WAITID) && !defined(__APPLE__)
6384PyDoc_STRVAR(posix_waitid__doc__,
6385"waitid(idtype, id, options) -> waitid_result\n\n\
6386Wait for the completion of one or more child processes.\n\n\
6387idtype can be P_PID, P_PGID or P_ALL.\n\
6388id specifies the pid to wait on.\n\
6389options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6390or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6391Returns either waitid_result or None if WNOHANG is specified and there are\n\
6392no children in a waitable state.");
6393
6394static PyObject *
6395posix_waitid(PyObject *self, PyObject *args)
6396{
6397 PyObject *result;
6398 idtype_t idtype;
6399 id_t id;
6400 int options, res;
6401 siginfo_t si;
6402 si.si_pid = 0;
6403 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6404 return NULL;
6405 Py_BEGIN_ALLOW_THREADS
6406 res = waitid(idtype, id, &si, options);
6407 Py_END_ALLOW_THREADS
6408 if (res == -1)
6409 return posix_error();
6410
6411 if (si.si_pid == 0)
6412 Py_RETURN_NONE;
6413
6414 result = PyStructSequence_New(&WaitidResultType);
6415 if (!result)
6416 return NULL;
6417
6418 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
6419 PyStructSequence_SET_ITEM(result, 1, PyLong_FromPid(si.si_uid));
6420 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6421 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6422 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6423 if (PyErr_Occurred()) {
6424 Py_DECREF(result);
6425 return NULL;
6426 }
6427
6428 return result;
6429}
6430#endif
6431
Guido van Rossumb6775db1994-08-01 11:34:53 +00006432#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006433PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006434"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006435Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006436
Barry Warsaw53699e91996-12-10 23:23:01 +00006437static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006438posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006439{
Victor Stinner8c62be82010-05-06 00:08:46 +00006440 pid_t pid;
6441 int options;
6442 WAIT_TYPE status;
6443 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006444
Victor Stinner8c62be82010-05-06 00:08:46 +00006445 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6446 return NULL;
6447 Py_BEGIN_ALLOW_THREADS
6448 pid = waitpid(pid, &status, options);
6449 Py_END_ALLOW_THREADS
6450 if (pid == -1)
6451 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006452
Victor Stinner8c62be82010-05-06 00:08:46 +00006453 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006454}
6455
Tim Petersab034fa2002-02-01 11:27:43 +00006456#elif defined(HAVE_CWAIT)
6457
6458/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006459PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006460"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006461"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006462
6463static PyObject *
6464posix_waitpid(PyObject *self, PyObject *args)
6465{
Victor Stinner8c62be82010-05-06 00:08:46 +00006466 Py_intptr_t pid;
6467 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006468
Victor Stinner8c62be82010-05-06 00:08:46 +00006469 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6470 return NULL;
6471 Py_BEGIN_ALLOW_THREADS
6472 pid = _cwait(&status, pid, options);
6473 Py_END_ALLOW_THREADS
6474 if (pid == -1)
6475 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006476
Victor Stinner8c62be82010-05-06 00:08:46 +00006477 /* shift the status left a byte so this is more like the POSIX waitpid */
6478 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006479}
6480#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006481
Guido van Rossumad0ee831995-03-01 10:34:45 +00006482#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006483PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006484"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006485Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006486
Barry Warsaw53699e91996-12-10 23:23:01 +00006487static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006488posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006489{
Victor Stinner8c62be82010-05-06 00:08:46 +00006490 pid_t pid;
6491 WAIT_TYPE status;
6492 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006493
Victor Stinner8c62be82010-05-06 00:08:46 +00006494 Py_BEGIN_ALLOW_THREADS
6495 pid = wait(&status);
6496 Py_END_ALLOW_THREADS
6497 if (pid == -1)
6498 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006499
Victor Stinner8c62be82010-05-06 00:08:46 +00006500 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006501}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006502#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006503
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006504
Larry Hastings9cf065c2012-06-22 16:30:09 -07006505#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
6506PyDoc_STRVAR(readlink__doc__,
6507"readlink(path, *, dir_fd=None) -> path\n\n\
6508Return a string representing the path to which the symbolic link points.\n\
6509\n\
6510If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6511 and path should be relative; path will then be relative to that directory.\n\
6512dir_fd may not be implemented on your platform.\n\
6513 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006514#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006515
Guido van Rossumb6775db1994-08-01 11:34:53 +00006516#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006517
Barry Warsaw53699e91996-12-10 23:23:01 +00006518static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006519posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006520{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006521 path_t path;
6522 int dir_fd = DEFAULT_DIR_FD;
6523 char buffer[MAXPATHLEN];
6524 ssize_t length;
6525 PyObject *return_value = NULL;
6526 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00006527
Larry Hastings9cf065c2012-06-22 16:30:09 -07006528 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01006529 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07006530 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
6531 path_converter, &path,
6532#ifdef HAVE_READLINKAT
6533 dir_fd_converter, &dir_fd
6534#else
6535 dir_fd_unavailable, &dir_fd
6536#endif
6537 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00006538 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00006539
Victor Stinner8c62be82010-05-06 00:08:46 +00006540 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07006541#ifdef HAVE_READLINKAT
6542 if (dir_fd != DEFAULT_DIR_FD)
6543 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00006544 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07006545#endif
6546 length = readlink(path.narrow, buffer, sizeof(buffer));
6547 Py_END_ALLOW_THREADS
6548
6549 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01006550 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006551 goto exit;
6552 }
6553
6554 if (PyUnicode_Check(path.object))
6555 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
6556 else
6557 return_value = PyBytes_FromStringAndSize(buffer, length);
6558exit:
6559 path_cleanup(&path);
6560 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006561}
Larry Hastings9cf065c2012-06-22 16:30:09 -07006562
6563
Guido van Rossumb6775db1994-08-01 11:34:53 +00006564#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006565
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006566
Larry Hastings9cf065c2012-06-22 16:30:09 -07006567#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006568PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07006569"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
6570Create a symbolic link pointing to src named dst.\n\n\
6571target_is_directory is required on Windows if the target is to be\n\
6572 interpreted as a directory. (On Windows, symlink requires\n\
6573 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
6574 target_is_directory is ignored on non-Windows platforms.\n\
6575\n\
6576If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6577 and path should be relative; path will then be relative to that directory.\n\
6578dir_fd may not be implemented on your platform.\n\
6579 If it is unavailable, using it will raise a NotImplementedError.");
6580
6581#if defined(MS_WINDOWS)
6582
6583/* Grab CreateSymbolicLinkW dynamically from kernel32 */
6584static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
6585static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
6586static int
6587check_CreateSymbolicLink()
6588{
6589 HINSTANCE hKernel32;
6590 /* only recheck */
6591 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
6592 return 1;
6593 hKernel32 = GetModuleHandleW(L"KERNEL32");
6594 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
6595 "CreateSymbolicLinkW");
6596 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
6597 "CreateSymbolicLinkA");
6598 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
6599}
6600
6601#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006602
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006603static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006604posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006605{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006606 path_t src;
6607 path_t dst;
6608 int dir_fd = DEFAULT_DIR_FD;
6609 int target_is_directory = 0;
6610 static char *keywords[] = {"src", "dst", "target_is_directory",
6611 "dir_fd", NULL};
6612 PyObject *return_value;
6613#ifdef MS_WINDOWS
6614 DWORD result;
6615#else
6616 int result;
6617#endif
6618
6619 memset(&src, 0, sizeof(src));
Victor Stinner292c8352012-10-30 02:17:38 +01006620 src.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07006621 src.argument_name = "src";
6622 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01006623 dst.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07006624 dst.argument_name = "dst";
6625
6626#ifdef MS_WINDOWS
6627 if (!check_CreateSymbolicLink()) {
6628 PyErr_SetString(PyExc_NotImplementedError,
6629 "CreateSymbolicLink functions not found");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03006630 return NULL;
6631 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07006632 if (!win32_can_symlink) {
6633 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03006634 return NULL;
6635 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07006636#endif
6637
6638 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
6639 keywords,
6640 path_converter, &src,
6641 path_converter, &dst,
6642 &target_is_directory,
6643#ifdef HAVE_SYMLINKAT
6644 dir_fd_converter, &dir_fd
6645#else
6646 dir_fd_unavailable, &dir_fd
6647#endif
6648 ))
6649 return NULL;
6650
6651 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
6652 PyErr_SetString(PyExc_ValueError,
6653 "symlink: src and dst must be the same type");
6654 return_value = NULL;
6655 goto exit;
6656 }
6657
6658#ifdef MS_WINDOWS
6659 Py_BEGIN_ALLOW_THREADS
6660 if (dst.wide)
6661 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
6662 target_is_directory);
6663 else
6664 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
6665 target_is_directory);
6666 Py_END_ALLOW_THREADS
6667
6668 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01006669 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006670 goto exit;
6671 }
6672
6673#else
6674
6675 Py_BEGIN_ALLOW_THREADS
6676#if HAVE_SYMLINKAT
6677 if (dir_fd != DEFAULT_DIR_FD)
6678 result = symlinkat(src.narrow, dir_fd, dst.narrow);
6679 else
6680#endif
6681 result = symlink(src.narrow, dst.narrow);
6682 Py_END_ALLOW_THREADS
6683
6684 if (result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01006685 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006686 goto exit;
6687 }
6688#endif
6689
6690 return_value = Py_None;
6691 Py_INCREF(Py_None);
6692 goto exit; /* silence "unused label" warning */
6693exit:
6694 path_cleanup(&src);
6695 path_cleanup(&dst);
6696 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006697}
Larry Hastings9cf065c2012-06-22 16:30:09 -07006698
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006699#endif /* HAVE_SYMLINK */
6700
Larry Hastings9cf065c2012-06-22 16:30:09 -07006701
Brian Curtind40e6f72010-07-08 21:39:08 +00006702#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
6703
Brian Curtind40e6f72010-07-08 21:39:08 +00006704static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006705win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00006706{
6707 wchar_t *path;
6708 DWORD n_bytes_returned;
6709 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006710 PyObject *po, *result;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03006711 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00006712 HANDLE reparse_point_handle;
6713
6714 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
6715 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
6716 wchar_t *print_name;
6717
Larry Hastings9cf065c2012-06-22 16:30:09 -07006718 static char *keywords[] = {"path", "dir_fd", NULL};
6719
6720 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
6721 &po,
6722 dir_fd_unavailable, &dir_fd
6723 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02006724 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07006725
Victor Stinnereb5657a2011-09-30 01:44:27 +02006726 path = PyUnicode_AsUnicode(po);
6727 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00006728 return NULL;
6729
6730 /* First get a handle to the reparse point */
6731 Py_BEGIN_ALLOW_THREADS
6732 reparse_point_handle = CreateFileW(
6733 path,
6734 0,
6735 0,
6736 0,
6737 OPEN_EXISTING,
6738 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
6739 0);
6740 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006741
Brian Curtind40e6f72010-07-08 21:39:08 +00006742 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006743 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006744
Brian Curtind40e6f72010-07-08 21:39:08 +00006745 Py_BEGIN_ALLOW_THREADS
6746 /* New call DeviceIoControl to read the reparse point */
6747 io_result = DeviceIoControl(
6748 reparse_point_handle,
6749 FSCTL_GET_REPARSE_POINT,
6750 0, 0, /* in buffer */
6751 target_buffer, sizeof(target_buffer),
6752 &n_bytes_returned,
6753 0 /* we're not using OVERLAPPED_IO */
6754 );
6755 CloseHandle(reparse_point_handle);
6756 Py_END_ALLOW_THREADS
6757
6758 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006759 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00006760
6761 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
6762 {
6763 PyErr_SetString(PyExc_ValueError,
6764 "not a symbolic link");
6765 return NULL;
6766 }
Brian Curtin74e45612010-07-09 15:58:59 +00006767 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
6768 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
6769
6770 result = PyUnicode_FromWideChar(print_name,
6771 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00006772 return result;
6773}
6774
6775#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
6776
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006777
Larry Hastings605a62d2012-06-24 04:33:36 -07006778static PyStructSequence_Field times_result_fields[] = {
6779 {"user", "user time"},
6780 {"system", "system time"},
6781 {"children_user", "user time of children"},
6782 {"children_system", "system time of children"},
6783 {"elapsed", "elapsed time since an arbitrary point in the past"},
6784 {NULL}
6785};
6786
6787PyDoc_STRVAR(times_result__doc__,
6788"times_result: Result from os.times().\n\n\
6789This object may be accessed either as a tuple of\n\
6790 (user, system, children_user, children_system, elapsed),\n\
6791or via the attributes user, system, children_user, children_system,\n\
6792and elapsed.\n\
6793\n\
6794See os.times for more information.");
6795
6796static PyStructSequence_Desc times_result_desc = {
6797 "times_result", /* name */
6798 times_result__doc__, /* doc */
6799 times_result_fields,
6800 5
6801};
6802
6803static PyTypeObject TimesResultType;
6804
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006805#ifdef MS_WINDOWS
6806#define HAVE_TIMES /* mandatory, for the method table */
6807#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07006808
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006809#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07006810
6811static PyObject *
6812build_times_result(double user, double system,
6813 double children_user, double children_system,
6814 double elapsed)
6815{
6816 PyObject *value = PyStructSequence_New(&TimesResultType);
6817 if (value == NULL)
6818 return NULL;
6819
6820#define SET(i, field) \
6821 { \
6822 PyObject *o = PyFloat_FromDouble(field); \
6823 if (!o) { \
6824 Py_DECREF(value); \
6825 return NULL; \
6826 } \
6827 PyStructSequence_SET_ITEM(value, i, o); \
6828 } \
6829
6830 SET(0, user);
6831 SET(1, system);
6832 SET(2, children_user);
6833 SET(3, children_system);
6834 SET(4, elapsed);
6835
6836#undef SET
6837
6838 return value;
6839}
6840
6841PyDoc_STRVAR(posix_times__doc__,
6842"times() -> times_result\n\n\
6843Return an object containing floating point numbers indicating process\n\
6844times. The object behaves like a named tuple with these fields:\n\
6845 (utime, stime, cutime, cstime, elapsed_time)");
6846
Jesus Ceaab70e2a2012-10-05 01:48:08 +02006847#if defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00006848static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006849posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006850{
Victor Stinner8c62be82010-05-06 00:08:46 +00006851 FILETIME create, exit, kernel, user;
6852 HANDLE hProc;
6853 hProc = GetCurrentProcess();
6854 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6855 /* The fields of a FILETIME structure are the hi and lo part
6856 of a 64-bit value expressed in 100 nanosecond units.
6857 1e7 is one second in such units; 1e-7 the inverse.
6858 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6859 */
Larry Hastings605a62d2012-06-24 04:33:36 -07006860 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00006861 (double)(user.dwHighDateTime*429.4967296 +
6862 user.dwLowDateTime*1e-7),
6863 (double)(kernel.dwHighDateTime*429.4967296 +
6864 kernel.dwLowDateTime*1e-7),
6865 (double)0,
6866 (double)0,
6867 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006868}
Jesus Ceaab70e2a2012-10-05 01:48:08 +02006869#else /* Not Windows */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006870#define NEED_TICKS_PER_SECOND
6871static long ticks_per_second = -1;
6872static PyObject *
6873posix_times(PyObject *self, PyObject *noargs)
6874{
6875 struct tms t;
6876 clock_t c;
6877 errno = 0;
6878 c = times(&t);
6879 if (c == (clock_t) -1)
6880 return posix_error();
6881 return build_times_result(
6882 (double)t.tms_utime / ticks_per_second,
6883 (double)t.tms_stime / ticks_per_second,
6884 (double)t.tms_cutime / ticks_per_second,
6885 (double)t.tms_cstime / ticks_per_second,
6886 (double)c / ticks_per_second);
6887}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006888#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006889
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006890#endif /* HAVE_TIMES */
6891
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006892
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006893#ifdef HAVE_GETSID
6894PyDoc_STRVAR(posix_getsid__doc__,
6895"getsid(pid) -> sid\n\n\
6896Call the system call getsid().");
6897
6898static PyObject *
6899posix_getsid(PyObject *self, PyObject *args)
6900{
Victor Stinner8c62be82010-05-06 00:08:46 +00006901 pid_t pid;
6902 int sid;
6903 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
6904 return NULL;
6905 sid = getsid(pid);
6906 if (sid < 0)
6907 return posix_error();
6908 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006909}
6910#endif /* HAVE_GETSID */
6911
6912
Guido van Rossumb6775db1994-08-01 11:34:53 +00006913#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006914PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006915"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006916Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006917
Barry Warsaw53699e91996-12-10 23:23:01 +00006918static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006919posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006920{
Victor Stinner8c62be82010-05-06 00:08:46 +00006921 if (setsid() < 0)
6922 return posix_error();
6923 Py_INCREF(Py_None);
6924 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006925}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006926#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006927
Guido van Rossumb6775db1994-08-01 11:34:53 +00006928#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006929PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006930"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006931Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006932
Barry Warsaw53699e91996-12-10 23:23:01 +00006933static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006934posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006935{
Victor Stinner8c62be82010-05-06 00:08:46 +00006936 pid_t pid;
6937 int pgrp;
6938 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
6939 return NULL;
6940 if (setpgid(pid, pgrp) < 0)
6941 return posix_error();
6942 Py_INCREF(Py_None);
6943 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006944}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006945#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006946
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006947
Guido van Rossumb6775db1994-08-01 11:34:53 +00006948#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006949PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006950"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006951Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006952
Barry Warsaw53699e91996-12-10 23:23:01 +00006953static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006954posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006955{
Victor Stinner8c62be82010-05-06 00:08:46 +00006956 int fd;
6957 pid_t pgid;
6958 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6959 return NULL;
6960 pgid = tcgetpgrp(fd);
6961 if (pgid < 0)
6962 return posix_error();
6963 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006964}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006965#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006966
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006967
Guido van Rossumb6775db1994-08-01 11:34:53 +00006968#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006969PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006970"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006971Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006972
Barry Warsaw53699e91996-12-10 23:23:01 +00006973static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006974posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006975{
Victor Stinner8c62be82010-05-06 00:08:46 +00006976 int fd;
6977 pid_t pgid;
6978 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
6979 return NULL;
6980 if (tcsetpgrp(fd, pgid) < 0)
6981 return posix_error();
6982 Py_INCREF(Py_None);
6983 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006984}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006985#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006986
Guido van Rossum687dd131993-05-17 08:34:16 +00006987/* Functions acting on file descriptors */
6988
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006989PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07006990"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
6991Open a file for low level IO. Returns a file handle (integer).\n\
6992\n\
6993If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6994 and path should be relative; path will then be relative to that directory.\n\
6995dir_fd may not be implemented on your platform.\n\
6996 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006997
Barry Warsaw53699e91996-12-10 23:23:01 +00006998static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006999posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007000{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007001 path_t path;
7002 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007003 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007004 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007005 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007006 PyObject *return_value = NULL;
7007 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007008
Larry Hastings9cf065c2012-06-22 16:30:09 -07007009 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007010 path.function_name = "open";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007011 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7012 path_converter, &path,
7013 &flags, &mode,
7014#ifdef HAVE_OPENAT
7015 dir_fd_converter, &dir_fd
7016#else
7017 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007018#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007019 ))
7020 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007021
Victor Stinner8c62be82010-05-06 00:08:46 +00007022 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007023#ifdef MS_WINDOWS
7024 if (path.wide)
7025 fd = _wopen(path.wide, flags, mode);
7026 else
7027#endif
7028#ifdef HAVE_OPENAT
7029 if (dir_fd != DEFAULT_DIR_FD)
7030 fd = openat(dir_fd, path.narrow, flags, mode);
7031 else
7032#endif
7033 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007034 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007035
Larry Hastings9cf065c2012-06-22 16:30:09 -07007036 if (fd == -1) {
Victor Stinner4e7d2d42012-11-05 01:20:58 +01007037 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path.object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007038 goto exit;
7039 }
7040
7041 return_value = PyLong_FromLong((long)fd);
7042
7043exit:
7044 path_cleanup(&path);
7045 return return_value;
7046}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007047
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007048PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007049"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007050Close a file descriptor (for low level IO).");
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_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007054{
Victor Stinner8c62be82010-05-06 00:08:46 +00007055 int fd, res;
7056 if (!PyArg_ParseTuple(args, "i:close", &fd))
7057 return NULL;
7058 if (!_PyVerify_fd(fd))
7059 return posix_error();
7060 Py_BEGIN_ALLOW_THREADS
7061 res = close(fd);
7062 Py_END_ALLOW_THREADS
7063 if (res < 0)
7064 return posix_error();
7065 Py_INCREF(Py_None);
7066 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007067}
7068
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007069
Victor Stinner8c62be82010-05-06 00:08:46 +00007070PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007071"closerange(fd_low, fd_high)\n\n\
7072Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7073
7074static PyObject *
7075posix_closerange(PyObject *self, PyObject *args)
7076{
Victor Stinner8c62be82010-05-06 00:08:46 +00007077 int fd_from, fd_to, i;
7078 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7079 return NULL;
7080 Py_BEGIN_ALLOW_THREADS
7081 for (i = fd_from; i < fd_to; i++)
7082 if (_PyVerify_fd(i))
7083 close(i);
7084 Py_END_ALLOW_THREADS
7085 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007086}
7087
7088
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007089PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007090"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007091Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007092
Barry Warsaw53699e91996-12-10 23:23:01 +00007093static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007094posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007095{
Victor Stinner8c62be82010-05-06 00:08:46 +00007096 int fd;
7097 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7098 return NULL;
7099 if (!_PyVerify_fd(fd))
7100 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007101 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007102 if (fd < 0)
7103 return posix_error();
7104 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007105}
7106
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007107
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007108PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007109"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007110Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007111
Barry Warsaw53699e91996-12-10 23:23:01 +00007112static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007113posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007114{
Victor Stinner8c62be82010-05-06 00:08:46 +00007115 int fd, fd2, res;
7116 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
7117 return NULL;
7118 if (!_PyVerify_fd_dup2(fd, fd2))
7119 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007120 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00007121 if (res < 0)
7122 return posix_error();
7123 Py_INCREF(Py_None);
7124 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007125}
7126
Ross Lagerwall7807c352011-03-17 20:20:30 +02007127#ifdef HAVE_LOCKF
7128PyDoc_STRVAR(posix_lockf__doc__,
7129"lockf(fd, cmd, len)\n\n\
7130Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7131fd is an open file descriptor.\n\
7132cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7133F_TEST.\n\
7134len specifies the section of the file to lock.");
7135
7136static PyObject *
7137posix_lockf(PyObject *self, PyObject *args)
7138{
7139 int fd, cmd, res;
7140 off_t len;
7141 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7142 &fd, &cmd, _parse_off_t, &len))
7143 return NULL;
7144
7145 Py_BEGIN_ALLOW_THREADS
7146 res = lockf(fd, cmd, len);
7147 Py_END_ALLOW_THREADS
7148
7149 if (res < 0)
7150 return posix_error();
7151
7152 Py_RETURN_NONE;
7153}
7154#endif
7155
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007156
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007157PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007158"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007159Set the current position of a file descriptor.\n\
7160Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007161
Barry Warsaw53699e91996-12-10 23:23:01 +00007162static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007163posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007164{
Victor Stinner8c62be82010-05-06 00:08:46 +00007165 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007166#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007167 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007168#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007169 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007170#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007171 PyObject *posobj;
7172 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007173 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007174#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007175 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7176 switch (how) {
7177 case 0: how = SEEK_SET; break;
7178 case 1: how = SEEK_CUR; break;
7179 case 2: how = SEEK_END; break;
7180 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007181#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007182
Ross Lagerwall8e749672011-03-17 21:54:07 +02007183#if !defined(HAVE_LARGEFILE_SUPPORT)
7184 pos = PyLong_AsLong(posobj);
7185#else
7186 pos = PyLong_AsLongLong(posobj);
7187#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007188 if (PyErr_Occurred())
7189 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007190
Victor Stinner8c62be82010-05-06 00:08:46 +00007191 if (!_PyVerify_fd(fd))
7192 return posix_error();
7193 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007194#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007195 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007196#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007197 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007198#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007199 Py_END_ALLOW_THREADS
7200 if (res < 0)
7201 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007202
7203#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007204 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007205#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007206 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007207#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007208}
7209
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007210
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007211PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007212"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007213Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007214
Barry Warsaw53699e91996-12-10 23:23:01 +00007215static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007216posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007217{
Victor Stinner8c62be82010-05-06 00:08:46 +00007218 int fd, size;
7219 Py_ssize_t n;
7220 PyObject *buffer;
7221 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7222 return NULL;
7223 if (size < 0) {
7224 errno = EINVAL;
7225 return posix_error();
7226 }
7227 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7228 if (buffer == NULL)
7229 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007230 if (!_PyVerify_fd(fd)) {
7231 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007232 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007233 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007234 Py_BEGIN_ALLOW_THREADS
7235 n = read(fd, PyBytes_AS_STRING(buffer), size);
7236 Py_END_ALLOW_THREADS
7237 if (n < 0) {
7238 Py_DECREF(buffer);
7239 return posix_error();
7240 }
7241 if (n != size)
7242 _PyBytes_Resize(&buffer, n);
7243 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007244}
7245
Ross Lagerwall7807c352011-03-17 20:20:30 +02007246#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7247 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007248static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007249iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7250{
7251 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007252 Py_ssize_t blen, total = 0;
7253
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007254 *iov = PyMem_New(struct iovec, cnt);
7255 if (*iov == NULL) {
7256 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007257 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007258 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007259
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007260 *buf = PyMem_New(Py_buffer, cnt);
7261 if (*buf == NULL) {
7262 PyMem_Del(*iov);
7263 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007264 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007265 }
7266
7267 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007268 PyObject *item = PySequence_GetItem(seq, i);
7269 if (item == NULL)
7270 goto fail;
7271 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7272 Py_DECREF(item);
7273 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007274 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007275 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007276 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007277 blen = (*buf)[i].len;
7278 (*iov)[i].iov_len = blen;
7279 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007280 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007281 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007282
7283fail:
7284 PyMem_Del(*iov);
7285 for (j = 0; j < i; j++) {
7286 PyBuffer_Release(&(*buf)[j]);
7287 }
7288 PyMem_Del(*buf);
7289 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007290}
7291
7292static void
7293iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7294{
7295 int i;
7296 PyMem_Del(iov);
7297 for (i = 0; i < cnt; i++) {
7298 PyBuffer_Release(&buf[i]);
7299 }
7300 PyMem_Del(buf);
7301}
7302#endif
7303
Ross Lagerwall7807c352011-03-17 20:20:30 +02007304#ifdef HAVE_READV
7305PyDoc_STRVAR(posix_readv__doc__,
7306"readv(fd, buffers) -> bytesread\n\n\
7307Read from a file descriptor into a number of writable buffers. buffers\n\
7308is an arbitrary sequence of writable buffers.\n\
7309Returns the total number of bytes read.");
7310
7311static PyObject *
7312posix_readv(PyObject *self, PyObject *args)
7313{
7314 int fd, cnt;
7315 Py_ssize_t n;
7316 PyObject *seq;
7317 struct iovec *iov;
7318 Py_buffer *buf;
7319
7320 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7321 return NULL;
7322 if (!PySequence_Check(seq)) {
7323 PyErr_SetString(PyExc_TypeError,
7324 "readv() arg 2 must be a sequence");
7325 return NULL;
7326 }
7327 cnt = PySequence_Size(seq);
7328
7329 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7330 return NULL;
7331
7332 Py_BEGIN_ALLOW_THREADS
7333 n = readv(fd, iov, cnt);
7334 Py_END_ALLOW_THREADS
7335
7336 iov_cleanup(iov, buf, cnt);
7337 return PyLong_FromSsize_t(n);
7338}
7339#endif
7340
7341#ifdef HAVE_PREAD
7342PyDoc_STRVAR(posix_pread__doc__,
7343"pread(fd, buffersize, offset) -> string\n\n\
7344Read from a file descriptor, fd, at a position of offset. It will read up\n\
7345to buffersize number of bytes. The file offset remains unchanged.");
7346
7347static PyObject *
7348posix_pread(PyObject *self, PyObject *args)
7349{
7350 int fd, size;
7351 off_t offset;
7352 Py_ssize_t n;
7353 PyObject *buffer;
7354 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7355 return NULL;
7356
7357 if (size < 0) {
7358 errno = EINVAL;
7359 return posix_error();
7360 }
7361 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7362 if (buffer == NULL)
7363 return NULL;
7364 if (!_PyVerify_fd(fd)) {
7365 Py_DECREF(buffer);
7366 return posix_error();
7367 }
7368 Py_BEGIN_ALLOW_THREADS
7369 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7370 Py_END_ALLOW_THREADS
7371 if (n < 0) {
7372 Py_DECREF(buffer);
7373 return posix_error();
7374 }
7375 if (n != size)
7376 _PyBytes_Resize(&buffer, n);
7377 return buffer;
7378}
7379#endif
7380
7381PyDoc_STRVAR(posix_write__doc__,
7382"write(fd, string) -> byteswritten\n\n\
7383Write a string to a file descriptor.");
7384
7385static PyObject *
7386posix_write(PyObject *self, PyObject *args)
7387{
7388 Py_buffer pbuf;
7389 int fd;
7390 Py_ssize_t size, len;
7391
7392 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
7393 return NULL;
7394 if (!_PyVerify_fd(fd)) {
7395 PyBuffer_Release(&pbuf);
7396 return posix_error();
7397 }
7398 len = pbuf.len;
7399 Py_BEGIN_ALLOW_THREADS
7400#if defined(MS_WIN64) || defined(MS_WINDOWS)
7401 if (len > INT_MAX)
7402 len = INT_MAX;
7403 size = write(fd, pbuf.buf, (int)len);
7404#else
7405 size = write(fd, pbuf.buf, len);
7406#endif
7407 Py_END_ALLOW_THREADS
7408 PyBuffer_Release(&pbuf);
7409 if (size < 0)
7410 return posix_error();
7411 return PyLong_FromSsize_t(size);
7412}
7413
7414#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007415PyDoc_STRVAR(posix_sendfile__doc__,
7416"sendfile(out, in, offset, nbytes) -> byteswritten\n\
7417sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
7418 -> byteswritten\n\
7419Copy nbytes bytes from file descriptor in to file descriptor out.");
7420
7421static PyObject *
7422posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
7423{
7424 int in, out;
7425 Py_ssize_t ret;
7426 off_t offset;
7427
7428#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
7429#ifndef __APPLE__
7430 Py_ssize_t len;
7431#endif
7432 PyObject *headers = NULL, *trailers = NULL;
7433 Py_buffer *hbuf, *tbuf;
7434 off_t sbytes;
7435 struct sf_hdtr sf;
7436 int flags = 0;
7437 sf.headers = NULL;
7438 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00007439 static char *keywords[] = {"out", "in",
7440 "offset", "count",
7441 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007442
7443#ifdef __APPLE__
7444 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007445 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007446#else
7447 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007448 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007449#endif
7450 &headers, &trailers, &flags))
7451 return NULL;
7452 if (headers != NULL) {
7453 if (!PySequence_Check(headers)) {
7454 PyErr_SetString(PyExc_TypeError,
7455 "sendfile() headers must be a sequence or None");
7456 return NULL;
7457 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007458 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007459 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007460 if (sf.hdr_cnt > 0 &&
7461 !(i = iov_setup(&(sf.headers), &hbuf,
7462 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007463 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007464#ifdef __APPLE__
7465 sbytes += i;
7466#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007467 }
7468 }
7469 if (trailers != NULL) {
7470 if (!PySequence_Check(trailers)) {
7471 PyErr_SetString(PyExc_TypeError,
7472 "sendfile() trailers must be a sequence or None");
7473 return NULL;
7474 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007475 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007476 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007477 if (sf.trl_cnt > 0 &&
7478 !(i = iov_setup(&(sf.trailers), &tbuf,
7479 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007480 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007481#ifdef __APPLE__
7482 sbytes += i;
7483#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007484 }
7485 }
7486
7487 Py_BEGIN_ALLOW_THREADS
7488#ifdef __APPLE__
7489 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
7490#else
7491 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
7492#endif
7493 Py_END_ALLOW_THREADS
7494
7495 if (sf.headers != NULL)
7496 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
7497 if (sf.trailers != NULL)
7498 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
7499
7500 if (ret < 0) {
7501 if ((errno == EAGAIN) || (errno == EBUSY)) {
7502 if (sbytes != 0) {
7503 // some data has been sent
7504 goto done;
7505 }
7506 else {
7507 // no data has been sent; upper application is supposed
7508 // to retry on EAGAIN or EBUSY
7509 return posix_error();
7510 }
7511 }
7512 return posix_error();
7513 }
7514 goto done;
7515
7516done:
7517 #if !defined(HAVE_LARGEFILE_SUPPORT)
7518 return Py_BuildValue("l", sbytes);
7519 #else
7520 return Py_BuildValue("L", sbytes);
7521 #endif
7522
7523#else
7524 Py_ssize_t count;
7525 PyObject *offobj;
7526 static char *keywords[] = {"out", "in",
7527 "offset", "count", NULL};
7528 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
7529 keywords, &out, &in, &offobj, &count))
7530 return NULL;
7531#ifdef linux
7532 if (offobj == Py_None) {
7533 Py_BEGIN_ALLOW_THREADS
7534 ret = sendfile(out, in, NULL, count);
7535 Py_END_ALLOW_THREADS
7536 if (ret < 0)
7537 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02007538 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007539 }
7540#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00007541 if (!_parse_off_t(offobj, &offset))
7542 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007543 Py_BEGIN_ALLOW_THREADS
7544 ret = sendfile(out, in, &offset, count);
7545 Py_END_ALLOW_THREADS
7546 if (ret < 0)
7547 return posix_error();
7548 return Py_BuildValue("n", ret);
7549#endif
7550}
7551#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007552
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007553PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007554"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07007555Like stat(), but for an open file descriptor.\n\
7556Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007557
Barry Warsaw53699e91996-12-10 23:23:01 +00007558static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007559posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007560{
Victor Stinner8c62be82010-05-06 00:08:46 +00007561 int fd;
7562 STRUCT_STAT st;
7563 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01007564 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007565 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007566#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00007567 /* on OpenVMS we must ensure that all bytes are written to the file */
7568 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007569#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007570 Py_BEGIN_ALLOW_THREADS
7571 res = FSTAT(fd, &st);
7572 Py_END_ALLOW_THREADS
7573 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00007574#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01007575 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00007576#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007577 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00007578#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007579 }
Tim Peters5aa91602002-01-30 05:46:57 +00007580
Victor Stinner4195b5c2012-02-08 23:03:19 +01007581 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00007582}
7583
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007584PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007585"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007586Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007587connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00007588
7589static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00007590posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00007591{
Victor Stinner8c62be82010-05-06 00:08:46 +00007592 int fd;
7593 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
7594 return NULL;
7595 if (!_PyVerify_fd(fd))
7596 return PyBool_FromLong(0);
7597 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00007598}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007599
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007600#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007601PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007602"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007603Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007604
Barry Warsaw53699e91996-12-10 23:23:01 +00007605static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007606posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007607{
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007608#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007609 int fds[2];
7610 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007611 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00007612 if (res != 0)
7613 return posix_error();
7614 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007615#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007616 HANDLE read, write;
7617 int read_fd, write_fd;
7618 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00007619 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00007620 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01007621 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00007622 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
7623 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
7624 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007625#endif /* MS_WINDOWS */
Guido van Rossum687dd131993-05-17 08:34:16 +00007626}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007627#endif /* HAVE_PIPE */
7628
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007629#ifdef HAVE_PIPE2
7630PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02007631"pipe2(flags) -> (read_end, write_end)\n\n\
7632Create a pipe with flags set atomically.\n\
7633flags can be constructed by ORing together one or more of these values:\n\
7634O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007635");
7636
7637static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02007638posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007639{
Charles-François Natali368f34b2011-06-06 19:49:47 +02007640 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007641 int fds[2];
7642 int res;
7643
Charles-François Natali368f34b2011-06-06 19:49:47 +02007644 flags = PyLong_AsLong(arg);
7645 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007646 return NULL;
7647
7648 res = pipe2(fds, flags);
7649 if (res != 0)
7650 return posix_error();
7651 return Py_BuildValue("(ii)", fds[0], fds[1]);
7652}
7653#endif /* HAVE_PIPE2 */
7654
Ross Lagerwall7807c352011-03-17 20:20:30 +02007655#ifdef HAVE_WRITEV
7656PyDoc_STRVAR(posix_writev__doc__,
7657"writev(fd, buffers) -> byteswritten\n\n\
7658Write the contents of buffers to a file descriptor, where buffers is an\n\
7659arbitrary sequence of buffers.\n\
7660Returns the total bytes written.");
7661
7662static PyObject *
7663posix_writev(PyObject *self, PyObject *args)
7664{
7665 int fd, cnt;
7666 Py_ssize_t res;
7667 PyObject *seq;
7668 struct iovec *iov;
7669 Py_buffer *buf;
7670 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
7671 return NULL;
7672 if (!PySequence_Check(seq)) {
7673 PyErr_SetString(PyExc_TypeError,
7674 "writev() arg 2 must be a sequence");
7675 return NULL;
7676 }
7677 cnt = PySequence_Size(seq);
7678
7679 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
7680 return NULL;
7681 }
7682
7683 Py_BEGIN_ALLOW_THREADS
7684 res = writev(fd, iov, cnt);
7685 Py_END_ALLOW_THREADS
7686
7687 iov_cleanup(iov, buf, cnt);
7688 return PyLong_FromSsize_t(res);
7689}
7690#endif
7691
7692#ifdef HAVE_PWRITE
7693PyDoc_STRVAR(posix_pwrite__doc__,
7694"pwrite(fd, string, offset) -> byteswritten\n\n\
7695Write string to a file descriptor, fd, from offset, leaving the file\n\
7696offset unchanged.");
7697
7698static PyObject *
7699posix_pwrite(PyObject *self, PyObject *args)
7700{
7701 Py_buffer pbuf;
7702 int fd;
7703 off_t offset;
7704 Py_ssize_t size;
7705
7706 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
7707 return NULL;
7708
7709 if (!_PyVerify_fd(fd)) {
7710 PyBuffer_Release(&pbuf);
7711 return posix_error();
7712 }
7713 Py_BEGIN_ALLOW_THREADS
7714 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
7715 Py_END_ALLOW_THREADS
7716 PyBuffer_Release(&pbuf);
7717 if (size < 0)
7718 return posix_error();
7719 return PyLong_FromSsize_t(size);
7720}
7721#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007722
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007723#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007724PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007725"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
7726Create a FIFO (a POSIX named pipe).\n\
7727\n\
7728If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7729 and path should be relative; path will then be relative to that directory.\n\
7730dir_fd may not be implemented on your platform.\n\
7731 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007732
Barry Warsaw53699e91996-12-10 23:23:01 +00007733static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007734posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007735{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007736 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00007737 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007738 int dir_fd = DEFAULT_DIR_FD;
7739 int result;
7740 PyObject *return_value = NULL;
7741 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
7742
7743 memset(&path, 0, sizeof(path));
7744 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
7745 path_converter, &path,
7746 &mode,
7747#ifdef HAVE_MKFIFOAT
7748 dir_fd_converter, &dir_fd
7749#else
7750 dir_fd_unavailable, &dir_fd
7751#endif
7752 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007753 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007754
Victor Stinner8c62be82010-05-06 00:08:46 +00007755 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007756#ifdef HAVE_MKFIFOAT
7757 if (dir_fd != DEFAULT_DIR_FD)
7758 result = mkfifoat(dir_fd, path.narrow, mode);
7759 else
7760#endif
7761 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007762 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007763
7764 if (result < 0) {
7765 return_value = posix_error();
7766 goto exit;
7767 }
7768
7769 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00007770 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007771
7772exit:
7773 path_cleanup(&path);
7774 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007775}
7776#endif
7777
Neal Norwitz11690112002-07-30 01:08:28 +00007778#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007779PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007780"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007781Create a filesystem node (file, device special file or named pipe)\n\
7782named filename. mode specifies both the permissions to use and the\n\
7783type of node to be created, being combined (bitwise OR) with one of\n\
7784S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007785device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07007786os.makedev()), otherwise it is ignored.\n\
7787\n\
7788If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7789 and path should be relative; path will then be relative to that directory.\n\
7790dir_fd may not be implemented on your platform.\n\
7791 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007792
7793
7794static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007795posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007796{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007797 path_t path;
7798 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00007799 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007800 int dir_fd = DEFAULT_DIR_FD;
7801 int result;
7802 PyObject *return_value = NULL;
7803 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
7804
7805 memset(&path, 0, sizeof(path));
7806 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
7807 path_converter, &path,
7808 &mode, &device,
7809#ifdef HAVE_MKNODAT
7810 dir_fd_converter, &dir_fd
7811#else
7812 dir_fd_unavailable, &dir_fd
7813#endif
7814 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007815 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007816
Victor Stinner8c62be82010-05-06 00:08:46 +00007817 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007818#ifdef HAVE_MKNODAT
7819 if (dir_fd != DEFAULT_DIR_FD)
7820 result = mknodat(dir_fd, path.narrow, mode, device);
7821 else
7822#endif
7823 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00007824 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007825
7826 if (result < 0) {
7827 return_value = posix_error();
7828 goto exit;
7829 }
7830
7831 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00007832 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02007833
Larry Hastings9cf065c2012-06-22 16:30:09 -07007834exit:
7835 path_cleanup(&path);
7836 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007837}
7838#endif
7839
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007840#ifdef HAVE_DEVICE_MACROS
7841PyDoc_STRVAR(posix_major__doc__,
7842"major(device) -> major number\n\
7843Extracts a device major number from a raw device number.");
7844
7845static PyObject *
7846posix_major(PyObject *self, PyObject *args)
7847{
Victor Stinner8c62be82010-05-06 00:08:46 +00007848 int device;
7849 if (!PyArg_ParseTuple(args, "i:major", &device))
7850 return NULL;
7851 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007852}
7853
7854PyDoc_STRVAR(posix_minor__doc__,
7855"minor(device) -> minor number\n\
7856Extracts a device minor number from a raw device number.");
7857
7858static PyObject *
7859posix_minor(PyObject *self, PyObject *args)
7860{
Victor Stinner8c62be82010-05-06 00:08:46 +00007861 int device;
7862 if (!PyArg_ParseTuple(args, "i:minor", &device))
7863 return NULL;
7864 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007865}
7866
7867PyDoc_STRVAR(posix_makedev__doc__,
7868"makedev(major, minor) -> device number\n\
7869Composes a raw device number from the major and minor device numbers.");
7870
7871static PyObject *
7872posix_makedev(PyObject *self, PyObject *args)
7873{
Victor Stinner8c62be82010-05-06 00:08:46 +00007874 int major, minor;
7875 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
7876 return NULL;
7877 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007878}
7879#endif /* device macros */
7880
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007881
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007882#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007883PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007884"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007885Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007886
Barry Warsaw53699e91996-12-10 23:23:01 +00007887static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007888posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007889{
Victor Stinner8c62be82010-05-06 00:08:46 +00007890 int fd;
7891 off_t length;
7892 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007893
Ross Lagerwall7807c352011-03-17 20:20:30 +02007894 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00007895 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007896
Victor Stinner8c62be82010-05-06 00:08:46 +00007897 Py_BEGIN_ALLOW_THREADS
7898 res = ftruncate(fd, length);
7899 Py_END_ALLOW_THREADS
7900 if (res < 0)
7901 return posix_error();
7902 Py_INCREF(Py_None);
7903 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007904}
7905#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007906
Ross Lagerwall7807c352011-03-17 20:20:30 +02007907#ifdef HAVE_TRUNCATE
7908PyDoc_STRVAR(posix_truncate__doc__,
7909"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02007910Truncate the file given by path to length bytes.\n\
7911On some platforms, path may also be specified as an open file descriptor.\n\
7912 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02007913
7914static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02007915posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02007916{
Georg Brandl306336b2012-06-24 12:55:33 +02007917 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007918 off_t length;
7919 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02007920 PyObject *result = NULL;
7921 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02007922
Georg Brandl306336b2012-06-24 12:55:33 +02007923 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007924 path.function_name = "truncate";
Georg Brandl306336b2012-06-24 12:55:33 +02007925#ifdef HAVE_FTRUNCATE
7926 path.allow_fd = 1;
7927#endif
7928 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
7929 path_converter, &path,
7930 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02007931 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007932
7933 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02007934#ifdef HAVE_FTRUNCATE
7935 if (path.fd != -1)
7936 res = ftruncate(path.fd, length);
7937 else
7938#endif
7939 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007940 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02007941 if (res < 0)
Victor Stinner292c8352012-10-30 02:17:38 +01007942 result = path_error(&path);
Georg Brandl306336b2012-06-24 12:55:33 +02007943 else {
7944 Py_INCREF(Py_None);
7945 result = Py_None;
7946 }
7947 path_cleanup(&path);
7948 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007949}
7950#endif
7951
7952#ifdef HAVE_POSIX_FALLOCATE
7953PyDoc_STRVAR(posix_posix_fallocate__doc__,
7954"posix_fallocate(fd, offset, len)\n\n\
7955Ensures that enough disk space is allocated for the file specified by fd\n\
7956starting from offset and continuing for len bytes.");
7957
7958static PyObject *
7959posix_posix_fallocate(PyObject *self, PyObject *args)
7960{
7961 off_t len, offset;
7962 int res, fd;
7963
7964 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
7965 &fd, _parse_off_t, &offset, _parse_off_t, &len))
7966 return NULL;
7967
7968 Py_BEGIN_ALLOW_THREADS
7969 res = posix_fallocate(fd, offset, len);
7970 Py_END_ALLOW_THREADS
7971 if (res != 0) {
7972 errno = res;
7973 return posix_error();
7974 }
7975 Py_RETURN_NONE;
7976}
7977#endif
7978
7979#ifdef HAVE_POSIX_FADVISE
7980PyDoc_STRVAR(posix_posix_fadvise__doc__,
7981"posix_fadvise(fd, offset, len, advice)\n\n\
7982Announces an intention to access data in a specific pattern thus allowing\n\
7983the kernel to make optimizations.\n\
7984The advice applies to the region of the file specified by fd starting at\n\
7985offset and continuing for len bytes.\n\
7986advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
7987POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
7988POSIX_FADV_DONTNEED.");
7989
7990static PyObject *
7991posix_posix_fadvise(PyObject *self, PyObject *args)
7992{
7993 off_t len, offset;
7994 int res, fd, advice;
7995
7996 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
7997 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
7998 return NULL;
7999
8000 Py_BEGIN_ALLOW_THREADS
8001 res = posix_fadvise(fd, offset, len, advice);
8002 Py_END_ALLOW_THREADS
8003 if (res != 0) {
8004 errno = res;
8005 return posix_error();
8006 }
8007 Py_RETURN_NONE;
8008}
8009#endif
8010
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008011#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008012PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008013"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008014Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008015
Fred Drake762e2061999-08-26 17:23:54 +00008016/* Save putenv() parameters as values here, so we can collect them when they
8017 * get re-set with another call for the same key. */
8018static PyObject *posix_putenv_garbage;
8019
Tim Peters5aa91602002-01-30 05:46:57 +00008020static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008021posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008022{
Victor Stinner84ae1182010-05-06 22:05:07 +00008023 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008024#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008025 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008026 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008027
Victor Stinner8c62be82010-05-06 00:08:46 +00008028 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008029 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008030 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008031 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008032
Victor Stinner65170952011-11-22 22:16:17 +01008033 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008034 if (newstr == NULL) {
8035 PyErr_NoMemory();
8036 goto error;
8037 }
Victor Stinner65170952011-11-22 22:16:17 +01008038 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8039 PyErr_Format(PyExc_ValueError,
8040 "the environment variable is longer than %u characters",
8041 _MAX_ENV);
8042 goto error;
8043 }
8044
Victor Stinner8c62be82010-05-06 00:08:46 +00008045 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008046 if (newenv == NULL)
8047 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008048 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008049 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008050 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008051 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008052#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008053 PyObject *os1, *os2;
8054 char *s1, *s2;
8055 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008056
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008057 if (!PyArg_ParseTuple(args,
8058 "O&O&:putenv",
8059 PyUnicode_FSConverter, &os1,
8060 PyUnicode_FSConverter, &os2))
8061 return NULL;
8062 s1 = PyBytes_AsString(os1);
8063 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008064
Victor Stinner65170952011-11-22 22:16:17 +01008065 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008066 if (newstr == NULL) {
8067 PyErr_NoMemory();
8068 goto error;
8069 }
8070
Victor Stinner8c62be82010-05-06 00:08:46 +00008071 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008072 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008073 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008074 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008075 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008076#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008077
Victor Stinner8c62be82010-05-06 00:08:46 +00008078 /* Install the first arg and newstr in posix_putenv_garbage;
8079 * this will cause previous value to be collected. This has to
8080 * happen after the real putenv() call because the old value
8081 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008082 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008083 /* really not much we can do; just leak */
8084 PyErr_Clear();
8085 }
8086 else {
8087 Py_DECREF(newstr);
8088 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008089
Martin v. Löwis011e8422009-05-05 04:43:17 +00008090#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008091 Py_DECREF(os1);
8092 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008093#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008094 Py_RETURN_NONE;
8095
8096error:
8097#ifndef MS_WINDOWS
8098 Py_DECREF(os1);
8099 Py_DECREF(os2);
8100#endif
8101 Py_XDECREF(newstr);
8102 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008103}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008104#endif /* putenv */
8105
Guido van Rossumc524d952001-10-19 01:31:59 +00008106#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008107PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008108"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008109Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008110
8111static PyObject *
8112posix_unsetenv(PyObject *self, PyObject *args)
8113{
Victor Stinner65170952011-11-22 22:16:17 +01008114 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008115#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008116 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008117#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008118
8119 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008120
Victor Stinner65170952011-11-22 22:16:17 +01008121 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008122 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008123
Victor Stinner984890f2011-11-24 13:53:38 +01008124#ifdef HAVE_BROKEN_UNSETENV
8125 unsetenv(PyBytes_AS_STRING(name));
8126#else
Victor Stinner65170952011-11-22 22:16:17 +01008127 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008128 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008129 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008130 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008131 }
Victor Stinner984890f2011-11-24 13:53:38 +01008132#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008133
Victor Stinner8c62be82010-05-06 00:08:46 +00008134 /* Remove the key from posix_putenv_garbage;
8135 * this will cause it to be collected. This has to
8136 * happen after the real unsetenv() call because the
8137 * old value was still accessible until then.
8138 */
Victor Stinner65170952011-11-22 22:16:17 +01008139 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008140 /* really not much we can do; just leak */
8141 PyErr_Clear();
8142 }
Victor Stinner65170952011-11-22 22:16:17 +01008143 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008144 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008145}
8146#endif /* unsetenv */
8147
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008148PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008149"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008150Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008151
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008152static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008153posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008154{
Victor Stinner8c62be82010-05-06 00:08:46 +00008155 int code;
8156 char *message;
8157 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8158 return NULL;
8159 message = strerror(code);
8160 if (message == NULL) {
8161 PyErr_SetString(PyExc_ValueError,
8162 "strerror() argument out of range");
8163 return NULL;
8164 }
Victor Stinner1b579672011-12-17 05:47:23 +01008165 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008166}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008167
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008168
Guido van Rossumc9641791998-08-04 15:26:23 +00008169#ifdef HAVE_SYS_WAIT_H
8170
Fred Drake106c1a02002-04-23 15:58:02 +00008171#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008172PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008173"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008174Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008175
8176static PyObject *
8177posix_WCOREDUMP(PyObject *self, PyObject *args)
8178{
Victor Stinner8c62be82010-05-06 00:08:46 +00008179 WAIT_TYPE status;
8180 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008181
Victor Stinner8c62be82010-05-06 00:08:46 +00008182 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8183 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008184
Victor Stinner8c62be82010-05-06 00:08:46 +00008185 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008186}
8187#endif /* WCOREDUMP */
8188
8189#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008190PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008191"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008192Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008193job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00008194
8195static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008196posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00008197{
Victor Stinner8c62be82010-05-06 00:08:46 +00008198 WAIT_TYPE status;
8199 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008200
Victor Stinner8c62be82010-05-06 00:08:46 +00008201 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
8202 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008203
Victor Stinner8c62be82010-05-06 00:08:46 +00008204 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008205}
8206#endif /* WIFCONTINUED */
8207
Guido van Rossumc9641791998-08-04 15:26:23 +00008208#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008209PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008210"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008211Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008212
8213static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008214posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008215{
Victor Stinner8c62be82010-05-06 00:08:46 +00008216 WAIT_TYPE status;
8217 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008218
Victor Stinner8c62be82010-05-06 00:08:46 +00008219 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
8220 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008221
Victor Stinner8c62be82010-05-06 00:08:46 +00008222 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008223}
8224#endif /* WIFSTOPPED */
8225
8226#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008227PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008228"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008229Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008230
8231static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008232posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008233{
Victor Stinner8c62be82010-05-06 00:08:46 +00008234 WAIT_TYPE status;
8235 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008236
Victor Stinner8c62be82010-05-06 00:08:46 +00008237 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8238 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008239
Victor Stinner8c62be82010-05-06 00:08:46 +00008240 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008241}
8242#endif /* WIFSIGNALED */
8243
8244#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008245PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008246"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008247Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008248system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008249
8250static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008251posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008252{
Victor Stinner8c62be82010-05-06 00:08:46 +00008253 WAIT_TYPE status;
8254 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008255
Victor Stinner8c62be82010-05-06 00:08:46 +00008256 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
8257 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008258
Victor Stinner8c62be82010-05-06 00:08:46 +00008259 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008260}
8261#endif /* WIFEXITED */
8262
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008263#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008264PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008265"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008266Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008267
8268static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008269posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008270{
Victor Stinner8c62be82010-05-06 00:08:46 +00008271 WAIT_TYPE status;
8272 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008273
Victor Stinner8c62be82010-05-06 00:08:46 +00008274 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8275 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008276
Victor Stinner8c62be82010-05-06 00:08:46 +00008277 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008278}
8279#endif /* WEXITSTATUS */
8280
8281#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008282PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008283"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008284Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008285value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008286
8287static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008288posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008289{
Victor Stinner8c62be82010-05-06 00:08:46 +00008290 WAIT_TYPE status;
8291 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008292
Victor Stinner8c62be82010-05-06 00:08:46 +00008293 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8294 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008295
Victor Stinner8c62be82010-05-06 00:08:46 +00008296 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008297}
8298#endif /* WTERMSIG */
8299
8300#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008301PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008302"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008303Return the signal that stopped the process that provided\n\
8304the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008305
8306static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008307posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008308{
Victor Stinner8c62be82010-05-06 00:08:46 +00008309 WAIT_TYPE status;
8310 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008311
Victor Stinner8c62be82010-05-06 00:08:46 +00008312 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8313 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008314
Victor Stinner8c62be82010-05-06 00:08:46 +00008315 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008316}
8317#endif /* WSTOPSIG */
8318
8319#endif /* HAVE_SYS_WAIT_H */
8320
8321
Thomas Wouters477c8d52006-05-27 19:21:47 +00008322#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00008323#ifdef _SCO_DS
8324/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
8325 needed definitions in sys/statvfs.h */
8326#define _SVID3
8327#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008328#include <sys/statvfs.h>
8329
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008330static PyObject*
8331_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008332 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8333 if (v == NULL)
8334 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008335
8336#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008337 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8338 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8339 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8340 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8341 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8342 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8343 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8344 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8345 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8346 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008347#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008348 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8349 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8350 PyStructSequence_SET_ITEM(v, 2,
8351 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8352 PyStructSequence_SET_ITEM(v, 3,
8353 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8354 PyStructSequence_SET_ITEM(v, 4,
8355 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8356 PyStructSequence_SET_ITEM(v, 5,
8357 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8358 PyStructSequence_SET_ITEM(v, 6,
8359 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8360 PyStructSequence_SET_ITEM(v, 7,
8361 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
8362 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8363 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008364#endif
8365
Victor Stinner8c62be82010-05-06 00:08:46 +00008366 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008367}
8368
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008369PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008370"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008371Perform an fstatvfs system call on the given fd.\n\
8372Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008373
8374static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008375posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008376{
Victor Stinner8c62be82010-05-06 00:08:46 +00008377 int fd, res;
8378 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008379
Victor Stinner8c62be82010-05-06 00:08:46 +00008380 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
8381 return NULL;
8382 Py_BEGIN_ALLOW_THREADS
8383 res = fstatvfs(fd, &st);
8384 Py_END_ALLOW_THREADS
8385 if (res != 0)
8386 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008387
Victor Stinner8c62be82010-05-06 00:08:46 +00008388 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008389}
Thomas Wouters477c8d52006-05-27 19:21:47 +00008390#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008391
8392
Thomas Wouters477c8d52006-05-27 19:21:47 +00008393#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008394#include <sys/statvfs.h>
8395
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008396PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008397"statvfs(path)\n\n\
8398Perform a statvfs system call on the given path.\n\
8399\n\
8400path may always be specified as a string.\n\
8401On some platforms, path may also be specified as an open file descriptor.\n\
8402 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008403
8404static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008405posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008406{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008407 static char *keywords[] = {"path", NULL};
8408 path_t path;
8409 int result;
8410 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008411 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008412
Larry Hastings9cf065c2012-06-22 16:30:09 -07008413 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008414 path.function_name = "statvfs";
Larry Hastings9cf065c2012-06-22 16:30:09 -07008415#ifdef HAVE_FSTATVFS
8416 path.allow_fd = 1;
8417#endif
8418 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
8419 path_converter, &path
8420 ))
8421 return NULL;
8422
8423 Py_BEGIN_ALLOW_THREADS
8424#ifdef HAVE_FSTATVFS
8425 if (path.fd != -1) {
8426#ifdef __APPLE__
8427 /* handle weak-linking on Mac OS X 10.3 */
8428 if (fstatvfs == NULL) {
8429 fd_specified("statvfs", path.fd);
8430 goto exit;
8431 }
8432#endif
8433 result = fstatvfs(path.fd, &st);
8434 }
8435 else
8436#endif
8437 result = statvfs(path.narrow, &st);
8438 Py_END_ALLOW_THREADS
8439
8440 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01008441 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008442 goto exit;
8443 }
8444
8445 return_value = _pystatvfs_fromstructstatvfs(st);
8446
8447exit:
8448 path_cleanup(&path);
8449 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00008450}
8451#endif /* HAVE_STATVFS */
8452
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008453#ifdef MS_WINDOWS
8454PyDoc_STRVAR(win32__getdiskusage__doc__,
8455"_getdiskusage(path) -> (total, free)\n\n\
8456Return disk usage statistics about the given path as (total, free) tuple.");
8457
8458static PyObject *
8459win32__getdiskusage(PyObject *self, PyObject *args)
8460{
8461 BOOL retval;
8462 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01008463 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008464
Victor Stinner6139c1b2011-11-09 22:14:14 +01008465 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008466 return NULL;
8467
8468 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01008469 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008470 Py_END_ALLOW_THREADS
8471 if (retval == 0)
8472 return PyErr_SetFromWindowsErr(0);
8473
8474 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
8475}
8476#endif
8477
8478
Fred Drakec9680921999-12-13 16:37:25 +00008479/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
8480 * It maps strings representing configuration variable names to
8481 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00008482 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00008483 * rarely-used constants. There are three separate tables that use
8484 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00008485 *
8486 * This code is always included, even if none of the interfaces that
8487 * need it are included. The #if hackery needed to avoid it would be
8488 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00008489 */
8490struct constdef {
8491 char *name;
8492 long value;
8493};
8494
Fred Drake12c6e2d1999-12-14 21:25:03 +00008495static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008496conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00008497 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00008498{
Christian Heimes217cfd12007-12-02 14:31:20 +00008499 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008500 *valuep = PyLong_AS_LONG(arg);
8501 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00008502 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00008503 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00008504 /* look up the value in the table using a binary search */
8505 size_t lo = 0;
8506 size_t mid;
8507 size_t hi = tablesize;
8508 int cmp;
8509 const char *confname;
8510 if (!PyUnicode_Check(arg)) {
8511 PyErr_SetString(PyExc_TypeError,
8512 "configuration names must be strings or integers");
8513 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008514 }
Stefan Krah0e803b32010-11-26 16:16:47 +00008515 confname = _PyUnicode_AsString(arg);
8516 if (confname == NULL)
8517 return 0;
8518 while (lo < hi) {
8519 mid = (lo + hi) / 2;
8520 cmp = strcmp(confname, table[mid].name);
8521 if (cmp < 0)
8522 hi = mid;
8523 else if (cmp > 0)
8524 lo = mid + 1;
8525 else {
8526 *valuep = table[mid].value;
8527 return 1;
8528 }
8529 }
8530 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
8531 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008532 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00008533}
8534
8535
8536#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
8537static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008538#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008539 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008540#endif
8541#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008542 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008543#endif
Fred Drakec9680921999-12-13 16:37:25 +00008544#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008545 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008546#endif
8547#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00008548 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00008549#endif
8550#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00008551 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00008552#endif
8553#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00008554 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00008555#endif
8556#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008557 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008558#endif
8559#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00008560 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00008561#endif
8562#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008563 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00008564#endif
8565#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008566 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008567#endif
8568#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008569 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00008570#endif
8571#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008572 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008573#endif
8574#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008575 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00008576#endif
8577#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008578 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008579#endif
8580#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008581 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00008582#endif
8583#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008584 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008585#endif
8586#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008587 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00008588#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00008589#ifdef _PC_ACL_ENABLED
8590 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
8591#endif
8592#ifdef _PC_MIN_HOLE_SIZE
8593 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
8594#endif
8595#ifdef _PC_ALLOC_SIZE_MIN
8596 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
8597#endif
8598#ifdef _PC_REC_INCR_XFER_SIZE
8599 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
8600#endif
8601#ifdef _PC_REC_MAX_XFER_SIZE
8602 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
8603#endif
8604#ifdef _PC_REC_MIN_XFER_SIZE
8605 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
8606#endif
8607#ifdef _PC_REC_XFER_ALIGN
8608 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
8609#endif
8610#ifdef _PC_SYMLINK_MAX
8611 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
8612#endif
8613#ifdef _PC_XATTR_ENABLED
8614 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
8615#endif
8616#ifdef _PC_XATTR_EXISTS
8617 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
8618#endif
8619#ifdef _PC_TIMESTAMP_RESOLUTION
8620 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
8621#endif
Fred Drakec9680921999-12-13 16:37:25 +00008622};
8623
Fred Drakec9680921999-12-13 16:37:25 +00008624static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008625conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008626{
8627 return conv_confname(arg, valuep, posix_constants_pathconf,
8628 sizeof(posix_constants_pathconf)
8629 / sizeof(struct constdef));
8630}
8631#endif
8632
8633#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008634PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008635"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008636Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008637If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00008638
8639static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008640posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008641{
8642 PyObject *result = NULL;
8643 int name, fd;
8644
Fred Drake12c6e2d1999-12-14 21:25:03 +00008645 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
8646 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008647 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008648
Stefan Krah0e803b32010-11-26 16:16:47 +00008649 errno = 0;
8650 limit = fpathconf(fd, name);
8651 if (limit == -1 && errno != 0)
8652 posix_error();
8653 else
8654 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008655 }
8656 return result;
8657}
8658#endif
8659
8660
8661#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008662PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008663"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008664Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008665If there is no limit, return -1.\n\
8666On some platforms, path may also be specified as an open file descriptor.\n\
8667 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00008668
8669static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008670posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00008671{
Georg Brandl306336b2012-06-24 12:55:33 +02008672 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00008673 PyObject *result = NULL;
8674 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02008675 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00008676
Georg Brandl306336b2012-06-24 12:55:33 +02008677 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008678 path.function_name = "pathconf";
Georg Brandl306336b2012-06-24 12:55:33 +02008679#ifdef HAVE_FPATHCONF
8680 path.allow_fd = 1;
8681#endif
8682 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
8683 path_converter, &path,
8684 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008685 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008686
Victor Stinner8c62be82010-05-06 00:08:46 +00008687 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02008688#ifdef HAVE_FPATHCONF
8689 if (path.fd != -1)
8690 limit = fpathconf(path.fd, name);
8691 else
8692#endif
8693 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00008694 if (limit == -1 && errno != 0) {
8695 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00008696 /* could be a path or name problem */
8697 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00008698 else
Victor Stinner292c8352012-10-30 02:17:38 +01008699 result = path_error(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00008700 }
8701 else
8702 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008703 }
Georg Brandl306336b2012-06-24 12:55:33 +02008704 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00008705 return result;
8706}
8707#endif
8708
8709#ifdef HAVE_CONFSTR
8710static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008711#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00008712 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00008713#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00008714#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008715 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008716#endif
8717#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008718 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008719#endif
Fred Draked86ed291999-12-15 15:34:33 +00008720#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008721 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008722#endif
8723#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008724 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008725#endif
8726#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008727 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008728#endif
8729#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008730 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008731#endif
Fred Drakec9680921999-12-13 16:37:25 +00008732#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008733 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008734#endif
8735#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008736 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008737#endif
8738#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008739 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008740#endif
8741#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008742 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008743#endif
8744#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008745 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008746#endif
8747#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008748 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008749#endif
8750#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008751 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008752#endif
8753#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008754 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008755#endif
Fred Draked86ed291999-12-15 15:34:33 +00008756#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00008757 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00008758#endif
Fred Drakec9680921999-12-13 16:37:25 +00008759#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00008760 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00008761#endif
Fred Draked86ed291999-12-15 15:34:33 +00008762#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008763 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00008764#endif
8765#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008766 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00008767#endif
8768#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008769 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008770#endif
8771#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008772 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00008773#endif
Fred Drakec9680921999-12-13 16:37:25 +00008774#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008775 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008776#endif
8777#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008778 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008779#endif
8780#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008781 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008782#endif
8783#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008784 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008785#endif
8786#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008787 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008788#endif
8789#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008790 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008791#endif
8792#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008793 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008794#endif
8795#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008796 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008797#endif
8798#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008799 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008800#endif
8801#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008802 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008803#endif
8804#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008805 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008806#endif
8807#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008808 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008809#endif
8810#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008811 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008812#endif
8813#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008814 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008815#endif
8816#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008817 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008818#endif
8819#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008820 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008821#endif
Fred Draked86ed291999-12-15 15:34:33 +00008822#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008823 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008824#endif
8825#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008826 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00008827#endif
8828#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00008829 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00008830#endif
8831#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008832 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008833#endif
8834#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008835 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008836#endif
8837#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00008838 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00008839#endif
8840#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008841 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00008842#endif
8843#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00008844 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00008845#endif
8846#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008847 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008848#endif
8849#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008850 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008851#endif
8852#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008853 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008854#endif
8855#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008856 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008857#endif
8858#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00008859 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00008860#endif
Fred Drakec9680921999-12-13 16:37:25 +00008861};
8862
8863static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008864conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008865{
8866 return conv_confname(arg, valuep, posix_constants_confstr,
8867 sizeof(posix_constants_confstr)
8868 / sizeof(struct constdef));
8869}
8870
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008871PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008872"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008873Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008874
8875static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008876posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008877{
8878 PyObject *result = NULL;
8879 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00008880 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00008881 int len;
Fred Drakec9680921999-12-13 16:37:25 +00008882
Victor Stinnercb043522010-09-10 23:49:04 +00008883 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
8884 return NULL;
8885
8886 errno = 0;
8887 len = confstr(name, buffer, sizeof(buffer));
8888 if (len == 0) {
8889 if (errno) {
8890 posix_error();
8891 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00008892 }
8893 else {
Victor Stinnercb043522010-09-10 23:49:04 +00008894 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00008895 }
8896 }
Victor Stinnercb043522010-09-10 23:49:04 +00008897
8898 if ((unsigned int)len >= sizeof(buffer)) {
8899 char *buf = PyMem_Malloc(len);
8900 if (buf == NULL)
8901 return PyErr_NoMemory();
8902 confstr(name, buf, len);
8903 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
8904 PyMem_Free(buf);
8905 }
8906 else
8907 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00008908 return result;
8909}
8910#endif
8911
8912
8913#ifdef HAVE_SYSCONF
8914static struct constdef posix_constants_sysconf[] = {
8915#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008916 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00008917#endif
8918#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00008919 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00008920#endif
8921#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008922 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008923#endif
8924#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008925 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008926#endif
8927#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008928 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008929#endif
8930#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00008931 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00008932#endif
8933#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00008934 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00008935#endif
8936#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008937 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008938#endif
8939#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00008940 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00008941#endif
8942#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008943 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008944#endif
Fred Draked86ed291999-12-15 15:34:33 +00008945#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008946 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008947#endif
8948#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00008949 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00008950#endif
Fred Drakec9680921999-12-13 16:37:25 +00008951#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008952 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008953#endif
Fred Drakec9680921999-12-13 16:37:25 +00008954#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008955 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008956#endif
8957#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008958 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008959#endif
8960#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008961 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008962#endif
8963#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008964 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008965#endif
8966#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008967 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008968#endif
Fred Draked86ed291999-12-15 15:34:33 +00008969#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008970 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00008971#endif
Fred Drakec9680921999-12-13 16:37:25 +00008972#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00008973 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008974#endif
8975#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008976 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008977#endif
8978#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008979 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008980#endif
8981#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008982 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008983#endif
8984#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008985 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008986#endif
Fred Draked86ed291999-12-15 15:34:33 +00008987#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00008988 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00008989#endif
Fred Drakec9680921999-12-13 16:37:25 +00008990#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008991 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008992#endif
8993#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008994 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008995#endif
8996#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008997 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008998#endif
8999#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009000 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009001#endif
9002#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009003 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009004#endif
9005#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009006 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009007#endif
9008#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009009 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009010#endif
9011#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009012 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009013#endif
9014#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009015 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009016#endif
9017#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009018 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009019#endif
9020#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009021 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009022#endif
9023#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009024 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009025#endif
9026#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009027 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009028#endif
9029#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009030 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009031#endif
9032#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009033 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009034#endif
9035#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009036 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009037#endif
9038#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009039 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009040#endif
9041#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009042 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009043#endif
9044#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009045 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009046#endif
9047#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009048 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009049#endif
9050#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009051 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009052#endif
9053#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009054 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009055#endif
9056#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009057 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009058#endif
Fred Draked86ed291999-12-15 15:34:33 +00009059#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009060 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009061#endif
Fred Drakec9680921999-12-13 16:37:25 +00009062#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009063 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009064#endif
9065#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009066 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009067#endif
9068#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009069 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009070#endif
Fred Draked86ed291999-12-15 15:34:33 +00009071#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009072 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009073#endif
Fred Drakec9680921999-12-13 16:37:25 +00009074#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009075 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009076#endif
Fred Draked86ed291999-12-15 15:34:33 +00009077#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009078 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009079#endif
9080#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009081 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009082#endif
Fred Drakec9680921999-12-13 16:37:25 +00009083#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009084 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009085#endif
9086#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009087 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009088#endif
9089#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009090 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009091#endif
9092#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009093 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009094#endif
Fred Draked86ed291999-12-15 15:34:33 +00009095#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009096 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009097#endif
Fred Drakec9680921999-12-13 16:37:25 +00009098#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009099 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009100#endif
9101#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009102 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009103#endif
9104#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009105 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009106#endif
9107#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009108 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009109#endif
9110#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009111 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009112#endif
9113#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009114 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009115#endif
9116#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009117 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009118#endif
Fred Draked86ed291999-12-15 15:34:33 +00009119#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009120 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009121#endif
Fred Drakec9680921999-12-13 16:37:25 +00009122#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009123 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009124#endif
9125#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009126 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009127#endif
Fred Draked86ed291999-12-15 15:34:33 +00009128#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009129 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009130#endif
Fred Drakec9680921999-12-13 16:37:25 +00009131#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009132 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009133#endif
9134#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009135 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009136#endif
9137#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009138 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009139#endif
9140#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009141 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009142#endif
9143#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009144 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009145#endif
9146#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009147 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009148#endif
9149#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009150 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009151#endif
9152#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009153 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009154#endif
9155#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009156 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009157#endif
Fred Draked86ed291999-12-15 15:34:33 +00009158#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009159 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009160#endif
9161#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009162 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009163#endif
Fred Drakec9680921999-12-13 16:37:25 +00009164#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009165 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009166#endif
9167#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009168 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009169#endif
9170#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009171 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009172#endif
9173#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009174 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009175#endif
9176#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009177 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009178#endif
9179#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009180 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009181#endif
9182#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009183 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009184#endif
9185#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009186 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009187#endif
9188#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009189 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009190#endif
9191#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009192 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009193#endif
9194#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00009195 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00009196#endif
9197#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009198 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00009199#endif
9200#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009201 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00009202#endif
9203#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00009204 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00009205#endif
9206#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00009207 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00009208#endif
9209#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00009210 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00009211#endif
9212#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00009213 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00009214#endif
9215#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009216 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009217#endif
9218#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009219 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009220#endif
9221#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00009222 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00009223#endif
9224#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009225 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009226#endif
9227#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009228 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009229#endif
9230#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00009231 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00009232#endif
9233#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009234 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009235#endif
9236#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009237 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009238#endif
9239#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009240 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00009241#endif
9242#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00009243 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00009244#endif
9245#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009246 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009247#endif
9248#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009249 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009250#endif
9251#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009252 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00009253#endif
9254#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009255 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009256#endif
9257#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009258 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009259#endif
9260#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009261 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009262#endif
9263#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009264 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009265#endif
9266#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009267 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009268#endif
Fred Draked86ed291999-12-15 15:34:33 +00009269#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00009270 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00009271#endif
Fred Drakec9680921999-12-13 16:37:25 +00009272#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00009273 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00009274#endif
9275#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009276 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009277#endif
9278#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00009279 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00009280#endif
9281#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009282 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009283#endif
9284#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009285 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009286#endif
9287#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009288 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009289#endif
9290#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00009291 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00009292#endif
9293#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009294 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009295#endif
9296#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009297 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009298#endif
9299#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009300 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009301#endif
9302#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009303 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009304#endif
9305#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009306 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00009307#endif
9308#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009309 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00009310#endif
9311#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00009312 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00009313#endif
9314#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009315 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009316#endif
9317#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009318 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009319#endif
9320#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009321 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009322#endif
9323#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009324 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00009325#endif
9326#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009327 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009328#endif
9329#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009330 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009331#endif
9332#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009333 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009334#endif
9335#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009336 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009337#endif
9338#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009339 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009340#endif
9341#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009342 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009343#endif
9344#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00009345 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00009346#endif
9347#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009348 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009349#endif
9350#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009351 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009352#endif
9353#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009354 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009355#endif
9356#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009357 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009358#endif
9359#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00009360 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00009361#endif
9362#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009363 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009364#endif
9365#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00009366 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00009367#endif
9368#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009369 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009370#endif
9371#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00009372 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00009373#endif
9374#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00009375 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00009376#endif
9377#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00009378 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00009379#endif
9380#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00009381 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00009382#endif
9383#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009384 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009385#endif
9386#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00009387 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00009388#endif
9389#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00009390 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00009391#endif
9392#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009393 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009394#endif
9395#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009396 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009397#endif
9398#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00009399 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00009400#endif
9401#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00009402 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00009403#endif
9404#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00009405 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00009406#endif
9407};
9408
9409static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009410conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009411{
9412 return conv_confname(arg, valuep, posix_constants_sysconf,
9413 sizeof(posix_constants_sysconf)
9414 / sizeof(struct constdef));
9415}
9416
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009417PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009418"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009419Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009420
9421static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009422posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009423{
9424 PyObject *result = NULL;
9425 int name;
9426
9427 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
9428 int value;
9429
9430 errno = 0;
9431 value = sysconf(name);
9432 if (value == -1 && errno != 0)
9433 posix_error();
9434 else
Christian Heimes217cfd12007-12-02 14:31:20 +00009435 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00009436 }
9437 return result;
9438}
9439#endif
9440
9441
Fred Drakebec628d1999-12-15 18:31:10 +00009442/* This code is used to ensure that the tables of configuration value names
9443 * are in sorted order as required by conv_confname(), and also to build the
9444 * the exported dictionaries that are used to publish information about the
9445 * names available on the host platform.
9446 *
9447 * Sorting the table at runtime ensures that the table is properly ordered
9448 * when used, even for platforms we're not able to test on. It also makes
9449 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00009450 */
Fred Drakebec628d1999-12-15 18:31:10 +00009451
9452static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009453cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00009454{
9455 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009456 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00009457 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009458 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00009459
9460 return strcmp(c1->name, c2->name);
9461}
9462
9463static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009464setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00009465 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009466{
Fred Drakebec628d1999-12-15 18:31:10 +00009467 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00009468 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00009469
9470 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
9471 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00009472 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00009473 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009474
Barry Warsaw3155db32000-04-13 15:20:40 +00009475 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009476 PyObject *o = PyLong_FromLong(table[i].value);
9477 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
9478 Py_XDECREF(o);
9479 Py_DECREF(d);
9480 return -1;
9481 }
9482 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00009483 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00009484 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00009485}
9486
Fred Drakebec628d1999-12-15 18:31:10 +00009487/* Return -1 on failure, 0 on success. */
9488static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00009489setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009490{
9491#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00009492 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00009493 sizeof(posix_constants_pathconf)
9494 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009495 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009496 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009497#endif
9498#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00009499 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00009500 sizeof(posix_constants_confstr)
9501 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009502 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009503 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009504#endif
9505#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00009506 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00009507 sizeof(posix_constants_sysconf)
9508 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009509 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009510 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009511#endif
Fred Drakebec628d1999-12-15 18:31:10 +00009512 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00009513}
Fred Draked86ed291999-12-15 15:34:33 +00009514
9515
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009516PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009517"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009518Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009519in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009520
9521static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009522posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009523{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009524 abort();
9525 /*NOTREACHED*/
9526 Py_FatalError("abort() called from Python code didn't abort!");
9527 return NULL;
9528}
Fred Drakebec628d1999-12-15 18:31:10 +00009529
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00009530#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009531PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00009532"startfile(filepath [, operation]) - Start a file with its associated\n\
9533application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009534\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00009535When \"operation\" is not specified or \"open\", this acts like\n\
9536double-clicking the file in Explorer, or giving the file name as an\n\
9537argument to the DOS \"start\" command: the file is opened with whatever\n\
9538application (if any) its extension is associated.\n\
9539When another \"operation\" is given, it specifies what should be done with\n\
9540the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009541\n\
9542startfile returns as soon as the associated application is launched.\n\
9543There is no option to wait for the application to close, and no way\n\
9544to retrieve the application's exit status.\n\
9545\n\
9546The filepath is relative to the current directory. If you want to use\n\
9547an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009548the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00009549
9550static PyObject *
9551win32_startfile(PyObject *self, PyObject *args)
9552{
Victor Stinner8c62be82010-05-06 00:08:46 +00009553 PyObject *ofilepath;
9554 char *filepath;
9555 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02009556 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +00009557 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00009558
Victor Stinnereb5657a2011-09-30 01:44:27 +02009559 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009560 if (!PyArg_ParseTuple(args, "U|s:startfile",
9561 &unipath, &operation)) {
9562 PyErr_Clear();
9563 goto normal;
9564 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009565
Victor Stinner8c62be82010-05-06 00:08:46 +00009566 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009567 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +00009568 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +02009569 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009570 PyErr_Clear();
9571 operation = NULL;
9572 goto normal;
9573 }
9574 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009575
Victor Stinnereb5657a2011-09-30 01:44:27 +02009576 wpath = PyUnicode_AsUnicode(unipath);
9577 if (wpath == NULL)
9578 goto normal;
9579 if (uoperation) {
9580 woperation = PyUnicode_AsUnicode(uoperation);
9581 if (woperation == NULL)
9582 goto normal;
9583 }
9584 else
9585 woperation = NULL;
9586
Victor Stinner8c62be82010-05-06 00:08:46 +00009587 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02009588 rc = ShellExecuteW((HWND)0, woperation, wpath,
9589 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +00009590 Py_END_ALLOW_THREADS
9591
Victor Stinnereb5657a2011-09-30 01:44:27 +02009592 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +00009593 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009594 win32_error_object("startfile", unipath);
9595 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009596 }
9597 Py_INCREF(Py_None);
9598 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009599
9600normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00009601 if (!PyArg_ParseTuple(args, "O&|s:startfile",
9602 PyUnicode_FSConverter, &ofilepath,
9603 &operation))
9604 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01009605 if (win32_warn_bytes_api()) {
9606 Py_DECREF(ofilepath);
9607 return NULL;
9608 }
Victor Stinner8c62be82010-05-06 00:08:46 +00009609 filepath = PyBytes_AsString(ofilepath);
9610 Py_BEGIN_ALLOW_THREADS
9611 rc = ShellExecute((HWND)0, operation, filepath,
9612 NULL, NULL, SW_SHOWNORMAL);
9613 Py_END_ALLOW_THREADS
9614 if (rc <= (HINSTANCE)32) {
9615 PyObject *errval = win32_error("startfile", filepath);
9616 Py_DECREF(ofilepath);
9617 return errval;
9618 }
9619 Py_DECREF(ofilepath);
9620 Py_INCREF(Py_None);
9621 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00009622}
9623#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009624
Martin v. Löwis438b5342002-12-27 10:16:42 +00009625#ifdef HAVE_GETLOADAVG
9626PyDoc_STRVAR(posix_getloadavg__doc__,
9627"getloadavg() -> (float, float, float)\n\n\
9628Return the number of processes in the system run queue averaged over\n\
9629the last 1, 5, and 15 minutes or raises OSError if the load average\n\
9630was unobtainable");
9631
9632static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009633posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00009634{
9635 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00009636 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009637 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
9638 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00009639 } else
Stefan Krah0e803b32010-11-26 16:16:47 +00009640 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00009641}
9642#endif
9643
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009644PyDoc_STRVAR(device_encoding__doc__,
9645"device_encoding(fd) -> str\n\n\
9646Return a string describing the encoding of the device\n\
9647if the output is a terminal; else return None.");
9648
9649static PyObject *
9650device_encoding(PyObject *self, PyObject *args)
9651{
Victor Stinner8c62be82010-05-06 00:08:46 +00009652 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -05009653
Victor Stinner8c62be82010-05-06 00:08:46 +00009654 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
9655 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -05009656
9657 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009658}
9659
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009660#ifdef HAVE_SETRESUID
9661PyDoc_STRVAR(posix_setresuid__doc__,
9662"setresuid(ruid, euid, suid)\n\n\
9663Set the current process's real, effective, and saved user ids.");
9664
9665static PyObject*
9666posix_setresuid (PyObject *self, PyObject *args)
9667{
Victor Stinner8c62be82010-05-06 00:08:46 +00009668 /* We assume uid_t is no larger than a long. */
9669 long ruid, euid, suid;
9670 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
9671 return NULL;
9672 if (setresuid(ruid, euid, suid) < 0)
9673 return posix_error();
9674 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009675}
9676#endif
9677
9678#ifdef HAVE_SETRESGID
9679PyDoc_STRVAR(posix_setresgid__doc__,
9680"setresgid(rgid, egid, sgid)\n\n\
9681Set the current process's real, effective, and saved group ids.");
9682
9683static PyObject*
9684posix_setresgid (PyObject *self, PyObject *args)
9685{
Victor Stinner8c62be82010-05-06 00:08:46 +00009686 /* We assume uid_t is no larger than a long. */
9687 long rgid, egid, sgid;
9688 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
9689 return NULL;
9690 if (setresgid(rgid, egid, sgid) < 0)
9691 return posix_error();
9692 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009693}
9694#endif
9695
9696#ifdef HAVE_GETRESUID
9697PyDoc_STRVAR(posix_getresuid__doc__,
9698"getresuid() -> (ruid, euid, suid)\n\n\
9699Get tuple of the current process's real, effective, and saved user ids.");
9700
9701static PyObject*
9702posix_getresuid (PyObject *self, PyObject *noargs)
9703{
Victor Stinner8c62be82010-05-06 00:08:46 +00009704 uid_t ruid, euid, suid;
9705 long l_ruid, l_euid, l_suid;
9706 if (getresuid(&ruid, &euid, &suid) < 0)
9707 return posix_error();
9708 /* Force the values into long's as we don't know the size of uid_t. */
9709 l_ruid = ruid;
9710 l_euid = euid;
9711 l_suid = suid;
9712 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009713}
9714#endif
9715
9716#ifdef HAVE_GETRESGID
9717PyDoc_STRVAR(posix_getresgid__doc__,
9718"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00009719Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009720
9721static PyObject*
9722posix_getresgid (PyObject *self, PyObject *noargs)
9723{
Victor Stinner8c62be82010-05-06 00:08:46 +00009724 uid_t rgid, egid, sgid;
9725 long l_rgid, l_egid, l_sgid;
9726 if (getresgid(&rgid, &egid, &sgid) < 0)
9727 return posix_error();
9728 /* Force the values into long's as we don't know the size of uid_t. */
9729 l_rgid = rgid;
9730 l_egid = egid;
9731 l_sgid = sgid;
9732 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009733}
9734#endif
9735
Benjamin Peterson9428d532011-09-14 11:45:52 -04009736#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -04009737
Benjamin Peterson799bd802011-08-31 22:15:17 -04009738PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009739"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
9740Return the value of extended attribute attribute on path.\n\
9741\n\
9742path may be either a string or an open file descriptor.\n\
9743If follow_symlinks is False, and the last element of the path is a symbolic\n\
9744 link, getxattr will examine the symbolic link itself instead of the file\n\
9745 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -04009746
9747static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009748posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04009749{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009750 path_t path;
9751 path_t attribute;
9752 int follow_symlinks = 1;
9753 PyObject *buffer = NULL;
9754 int i;
9755 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -04009756
Larry Hastings9cf065c2012-06-22 16:30:09 -07009757 memset(&path, 0, sizeof(path));
9758 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +01009759 path.function_name = "getxattr";
9760 attribute.function_name = "getxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009761 path.allow_fd = 1;
9762 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
9763 path_converter, &path,
9764 path_converter, &attribute,
9765 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -04009766 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009767
Larry Hastings9cf065c2012-06-22 16:30:09 -07009768 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
9769 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009770
Larry Hastings9cf065c2012-06-22 16:30:09 -07009771 for (i = 0; ; i++) {
9772 void *ptr;
9773 ssize_t result;
9774 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
9775 Py_ssize_t buffer_size = buffer_sizes[i];
9776 if (!buffer_size) {
Victor Stinner292c8352012-10-30 02:17:38 +01009777 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009778 goto exit;
9779 }
9780 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
9781 if (!buffer)
9782 goto exit;
9783 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009784
Larry Hastings9cf065c2012-06-22 16:30:09 -07009785 Py_BEGIN_ALLOW_THREADS;
9786 if (path.fd >= 0)
9787 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
9788 else if (follow_symlinks)
9789 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
9790 else
9791 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
9792 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009793
Larry Hastings9cf065c2012-06-22 16:30:09 -07009794 if (result < 0) {
9795 Py_DECREF(buffer);
9796 buffer = NULL;
9797 if (errno == ERANGE)
9798 continue;
Victor Stinner292c8352012-10-30 02:17:38 +01009799 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009800 goto exit;
9801 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009802
Larry Hastings9cf065c2012-06-22 16:30:09 -07009803 if (result != buffer_size) {
9804 /* Can only shrink. */
9805 _PyBytes_Resize(&buffer, result);
9806 }
9807 break;
9808 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009809
Larry Hastings9cf065c2012-06-22 16:30:09 -07009810exit:
9811 path_cleanup(&path);
9812 path_cleanup(&attribute);
9813 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009814}
9815
9816PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009817"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
9818Set extended attribute attribute on path to value.\n\
9819path may be either a string or an open file descriptor.\n\
9820If follow_symlinks is False, and the last element of the path is a symbolic\n\
9821 link, setxattr will modify the symbolic link itself instead of the file\n\
9822 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -04009823
9824static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009825posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04009826{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009827 path_t path;
9828 path_t attribute;
9829 Py_buffer value;
9830 int flags = 0;
9831 int follow_symlinks = 1;
9832 int result;
9833 PyObject *return_value = NULL;
9834 static char *keywords[] = {"path", "attribute", "value",
9835 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -04009836
Larry Hastings9cf065c2012-06-22 16:30:09 -07009837 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009838 path.function_name = "setxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009839 path.allow_fd = 1;
9840 memset(&attribute, 0, sizeof(attribute));
9841 memset(&value, 0, sizeof(value));
9842 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
9843 keywords,
9844 path_converter, &path,
9845 path_converter, &attribute,
9846 &value, &flags,
9847 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -04009848 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009849
9850 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
9851 goto exit;
9852
Benjamin Peterson799bd802011-08-31 22:15:17 -04009853 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009854 if (path.fd > -1)
9855 result = fsetxattr(path.fd, attribute.narrow,
9856 value.buf, value.len, flags);
9857 else if (follow_symlinks)
9858 result = setxattr(path.narrow, attribute.narrow,
9859 value.buf, value.len, flags);
9860 else
9861 result = lsetxattr(path.narrow, attribute.narrow,
9862 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009863 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009864
Larry Hastings9cf065c2012-06-22 16:30:09 -07009865 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01009866 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009867 goto exit;
9868 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009869
Larry Hastings9cf065c2012-06-22 16:30:09 -07009870 return_value = Py_None;
9871 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009872
Larry Hastings9cf065c2012-06-22 16:30:09 -07009873exit:
9874 path_cleanup(&path);
9875 path_cleanup(&attribute);
9876 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009877
Larry Hastings9cf065c2012-06-22 16:30:09 -07009878 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009879}
9880
9881PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009882"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
9883Remove extended attribute attribute on path.\n\
9884path may be either a string or an open file descriptor.\n\
9885If follow_symlinks is False, and the last element of the path is a symbolic\n\
9886 link, removexattr will modify the symbolic link itself instead of the file\n\
9887 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -04009888
9889static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009890posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04009891{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009892 path_t path;
9893 path_t attribute;
9894 int follow_symlinks = 1;
9895 int result;
9896 PyObject *return_value = NULL;
9897 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -04009898
Larry Hastings9cf065c2012-06-22 16:30:09 -07009899 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009900 path.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009901 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +01009902 attribute.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009903 path.allow_fd = 1;
9904 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
9905 keywords,
9906 path_converter, &path,
9907 path_converter, &attribute,
9908 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -04009909 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009910
9911 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
9912 goto exit;
9913
Benjamin Peterson799bd802011-08-31 22:15:17 -04009914 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009915 if (path.fd > -1)
9916 result = fremovexattr(path.fd, attribute.narrow);
9917 else if (follow_symlinks)
9918 result = removexattr(path.narrow, attribute.narrow);
9919 else
9920 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009921 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009922
Larry Hastings9cf065c2012-06-22 16:30:09 -07009923 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01009924 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009925 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009926 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009927
Larry Hastings9cf065c2012-06-22 16:30:09 -07009928 return_value = Py_None;
9929 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009930
Larry Hastings9cf065c2012-06-22 16:30:09 -07009931exit:
9932 path_cleanup(&path);
9933 path_cleanup(&attribute);
9934
9935 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009936}
9937
9938PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009939"listxattr(path='.', *, follow_symlinks=True)\n\n\
9940Return a list of extended attributes on path.\n\
9941\n\
9942path may be either None, a string, or an open file descriptor.\n\
9943if path is None, listxattr will examine the current directory.\n\
9944If follow_symlinks is False, and the last element of the path is a symbolic\n\
9945 link, listxattr will examine the symbolic link itself instead of the file\n\
9946 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -04009947
9948static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009949posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04009950{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009951 path_t path;
9952 int follow_symlinks = 1;
9953 Py_ssize_t i;
9954 PyObject *result = NULL;
9955 char *buffer = NULL;
9956 char *name;
9957 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -04009958
Larry Hastings9cf065c2012-06-22 16:30:09 -07009959 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009960 path.function_name = "listxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009961 path.allow_fd = 1;
9962 path.fd = -1;
9963 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
9964 path_converter, &path,
9965 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -04009966 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009967
Larry Hastings9cf065c2012-06-22 16:30:09 -07009968 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
9969 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009970
Larry Hastings9cf065c2012-06-22 16:30:09 -07009971 name = path.narrow ? path.narrow : ".";
9972 for (i = 0; ; i++) {
9973 char *start, *trace, *end;
9974 ssize_t length;
9975 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
9976 Py_ssize_t buffer_size = buffer_sizes[i];
9977 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +02009978 /* ERANGE */
Victor Stinner292c8352012-10-30 02:17:38 +01009979 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009980 break;
9981 }
9982 buffer = PyMem_MALLOC(buffer_size);
9983 if (!buffer) {
9984 PyErr_NoMemory();
9985 break;
9986 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009987
Larry Hastings9cf065c2012-06-22 16:30:09 -07009988 Py_BEGIN_ALLOW_THREADS;
9989 if (path.fd > -1)
9990 length = flistxattr(path.fd, buffer, buffer_size);
9991 else if (follow_symlinks)
9992 length = listxattr(name, buffer, buffer_size);
9993 else
9994 length = llistxattr(name, buffer, buffer_size);
9995 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009996
Larry Hastings9cf065c2012-06-22 16:30:09 -07009997 if (length < 0) {
9998 if (errno == ERANGE)
9999 continue;
Victor Stinner292c8352012-10-30 02:17:38 +010010000 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010001 break;
10002 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010003
Larry Hastings9cf065c2012-06-22 16:30:09 -070010004 result = PyList_New(0);
10005 if (!result) {
10006 goto exit;
10007 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010008
Larry Hastings9cf065c2012-06-22 16:30:09 -070010009 end = buffer + length;
10010 for (trace = start = buffer; trace != end; trace++) {
10011 if (!*trace) {
10012 int error;
10013 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10014 trace - start);
10015 if (!attribute) {
10016 Py_DECREF(result);
10017 result = NULL;
10018 goto exit;
10019 }
10020 error = PyList_Append(result, attribute);
10021 Py_DECREF(attribute);
10022 if (error) {
10023 Py_DECREF(result);
10024 result = NULL;
10025 goto exit;
10026 }
10027 start = trace + 1;
10028 }
10029 }
10030 break;
10031 }
10032exit:
10033 path_cleanup(&path);
10034 if (buffer)
10035 PyMem_FREE(buffer);
10036 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010037}
10038
Benjamin Peterson9428d532011-09-14 11:45:52 -040010039#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010040
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010041
Georg Brandl2fb477c2012-02-21 00:33:36 +010010042PyDoc_STRVAR(posix_urandom__doc__,
10043"urandom(n) -> str\n\n\
10044Return n random bytes suitable for cryptographic use.");
10045
10046static PyObject *
10047posix_urandom(PyObject *self, PyObject *args)
10048{
10049 Py_ssize_t size;
10050 PyObject *result;
10051 int ret;
10052
10053 /* Read arguments */
10054 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10055 return NULL;
10056 if (size < 0)
10057 return PyErr_Format(PyExc_ValueError,
10058 "negative argument not allowed");
10059 result = PyBytes_FromStringAndSize(NULL, size);
10060 if (result == NULL)
10061 return NULL;
10062
10063 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10064 PyBytes_GET_SIZE(result));
10065 if (ret == -1) {
10066 Py_DECREF(result);
10067 return NULL;
10068 }
10069 return result;
10070}
10071
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010072/* Terminal size querying */
10073
10074static PyTypeObject TerminalSizeType;
10075
10076PyDoc_STRVAR(TerminalSize_docstring,
10077 "A tuple of (columns, lines) for holding terminal window size");
10078
10079static PyStructSequence_Field TerminalSize_fields[] = {
10080 {"columns", "width of the terminal window in characters"},
10081 {"lines", "height of the terminal window in characters"},
10082 {NULL, NULL}
10083};
10084
10085static PyStructSequence_Desc TerminalSize_desc = {
10086 "os.terminal_size",
10087 TerminalSize_docstring,
10088 TerminalSize_fields,
10089 2,
10090};
10091
10092#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10093PyDoc_STRVAR(termsize__doc__,
10094 "Return the size of the terminal window as (columns, lines).\n" \
10095 "\n" \
10096 "The optional argument fd (default standard output) specifies\n" \
10097 "which file descriptor should be queried.\n" \
10098 "\n" \
10099 "If the file descriptor is not connected to a terminal, an OSError\n" \
10100 "is thrown.\n" \
10101 "\n" \
10102 "This function will only be defined if an implementation is\n" \
10103 "available for this system.\n" \
10104 "\n" \
10105 "shutil.get_terminal_size is the high-level function which should \n" \
10106 "normally be used, os.get_terminal_size is the low-level implementation.");
10107
10108static PyObject*
10109get_terminal_size(PyObject *self, PyObject *args)
10110{
10111 int columns, lines;
10112 PyObject *termsize;
10113
10114 int fd = fileno(stdout);
10115 /* Under some conditions stdout may not be connected and
10116 * fileno(stdout) may point to an invalid file descriptor. For example
10117 * GUI apps don't have valid standard streams by default.
10118 *
10119 * If this happens, and the optional fd argument is not present,
10120 * the ioctl below will fail returning EBADF. This is what we want.
10121 */
10122
10123 if (!PyArg_ParseTuple(args, "|i", &fd))
10124 return NULL;
10125
10126#ifdef TERMSIZE_USE_IOCTL
10127 {
10128 struct winsize w;
10129 if (ioctl(fd, TIOCGWINSZ, &w))
10130 return PyErr_SetFromErrno(PyExc_OSError);
10131 columns = w.ws_col;
10132 lines = w.ws_row;
10133 }
10134#endif /* TERMSIZE_USE_IOCTL */
10135
10136#ifdef TERMSIZE_USE_CONIO
10137 {
10138 DWORD nhandle;
10139 HANDLE handle;
10140 CONSOLE_SCREEN_BUFFER_INFO csbi;
10141 switch (fd) {
10142 case 0: nhandle = STD_INPUT_HANDLE;
10143 break;
10144 case 1: nhandle = STD_OUTPUT_HANDLE;
10145 break;
10146 case 2: nhandle = STD_ERROR_HANDLE;
10147 break;
10148 default:
10149 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10150 }
10151 handle = GetStdHandle(nhandle);
10152 if (handle == NULL)
10153 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10154 if (handle == INVALID_HANDLE_VALUE)
10155 return PyErr_SetFromWindowsErr(0);
10156
10157 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10158 return PyErr_SetFromWindowsErr(0);
10159
10160 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10161 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10162 }
10163#endif /* TERMSIZE_USE_CONIO */
10164
10165 termsize = PyStructSequence_New(&TerminalSizeType);
10166 if (termsize == NULL)
10167 return NULL;
10168 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10169 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10170 if (PyErr_Occurred()) {
10171 Py_DECREF(termsize);
10172 return NULL;
10173 }
10174 return termsize;
10175}
10176#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10177
10178
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010179static PyMethodDef posix_methods[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010180 {"access", (PyCFunction)posix_access,
10181 METH_VARARGS | METH_KEYWORDS,
10182 posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010183#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010184 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010185#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010186 {"chdir", (PyCFunction)posix_chdir,
10187 METH_VARARGS | METH_KEYWORDS,
10188 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010189#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010190 {"chflags", (PyCFunction)posix_chflags,
10191 METH_VARARGS | METH_KEYWORDS,
10192 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010193#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010194 {"chmod", (PyCFunction)posix_chmod,
10195 METH_VARARGS | METH_KEYWORDS,
10196 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010197#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010198 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010199#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010200#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070010201 {"chown", (PyCFunction)posix_chown,
10202 METH_VARARGS | METH_KEYWORDS,
10203 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010204#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010205#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010207#endif /* HAVE_LCHMOD */
10208#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010209 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010210#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010211#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010213#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010214#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010216#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010217#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010218 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010219#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010220#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010221 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010222#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010223#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010224 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10225 METH_NOARGS, posix_getcwd__doc__},
10226 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10227 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010228#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010229#if defined(HAVE_LINK) || defined(MS_WINDOWS)
10230 {"link", (PyCFunction)posix_link,
10231 METH_VARARGS | METH_KEYWORDS,
10232 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010233#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010234 {"listdir", (PyCFunction)posix_listdir,
10235 METH_VARARGS | METH_KEYWORDS,
10236 posix_listdir__doc__},
10237 {"lstat", (PyCFunction)posix_lstat,
10238 METH_VARARGS | METH_KEYWORDS,
10239 posix_lstat__doc__},
10240 {"mkdir", (PyCFunction)posix_mkdir,
10241 METH_VARARGS | METH_KEYWORDS,
10242 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010243#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010244 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000010245#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010246#ifdef HAVE_GETPRIORITY
10247 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10248#endif /* HAVE_GETPRIORITY */
10249#ifdef HAVE_SETPRIORITY
10250 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10251#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010252#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070010253 {"readlink", (PyCFunction)posix_readlink,
10254 METH_VARARGS | METH_KEYWORDS,
10255 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010256#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010257#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010258 {"readlink", (PyCFunction)win_readlink,
10259 METH_VARARGS | METH_KEYWORDS,
10260 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010261#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010262 {"rename", (PyCFunction)posix_rename,
10263 METH_VARARGS | METH_KEYWORDS,
10264 posix_rename__doc__},
10265 {"replace", (PyCFunction)posix_replace,
10266 METH_VARARGS | METH_KEYWORDS,
10267 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070010268 {"rmdir", (PyCFunction)posix_rmdir,
10269 METH_VARARGS | METH_KEYWORDS,
10270 posix_rmdir__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010271 {"stat", (PyCFunction)posix_stat,
10272 METH_VARARGS | METH_KEYWORDS,
10273 posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010274 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010275#if defined(HAVE_SYMLINK)
10276 {"symlink", (PyCFunction)posix_symlink,
10277 METH_VARARGS | METH_KEYWORDS,
10278 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010279#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000010280#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010281 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010282#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010283 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010284#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010285 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010286#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010287 {"unlink", (PyCFunction)posix_unlink,
10288 METH_VARARGS | METH_KEYWORDS,
10289 posix_unlink__doc__},
10290 {"remove", (PyCFunction)posix_unlink,
10291 METH_VARARGS | METH_KEYWORDS,
10292 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070010293 {"utime", (PyCFunction)posix_utime,
10294 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000010295#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010296 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010297#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010298 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010299#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010300 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010301 {"execve", (PyCFunction)posix_execve,
10302 METH_VARARGS | METH_KEYWORDS,
10303 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010304#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000010305#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010306 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10307 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +000010308#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010309#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010310 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010311#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010312#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010313 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010314#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010315#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010316#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010317 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
10318 {"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 +020010319#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010320#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010321 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010322#endif
10323#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010324 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010325#endif
10326#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010327 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010328#endif
10329#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010330 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010331#endif
10332#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010333 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010334#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010335 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050010336#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010337 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
10338 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
10339#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010340#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010341#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000010342 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010343#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000010344#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010345 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000010346#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000010347#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010348 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000010349#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010350#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010351 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000010352#endif /* HAVE_GETEUID */
10353#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010354 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010355#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020010356#ifdef HAVE_GETGROUPLIST
10357 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
10358#endif
Fred Drakec9680921999-12-13 16:37:25 +000010359#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010360 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010361#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010362 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010363#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010364 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010365#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010366#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010367 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010368#endif /* HAVE_GETPPID */
10369#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010370 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010371#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000010372#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010373 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000010374#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000010375#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000010376 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010377#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010378#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000010379 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010380#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000010381#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010382 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000010383#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000010384#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010385 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
10386 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000010387#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010388#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010389 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010390#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010391#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010392 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010393#endif /* HAVE_SETEUID */
10394#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010395 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010396#endif /* HAVE_SETEGID */
10397#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010398 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010399#endif /* HAVE_SETREUID */
10400#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010401 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010402#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010403#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010404 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010405#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010406#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010407 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010408#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000010409#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010410 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000010411#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000010412#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010413 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000010414#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010415#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010416 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010417#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010418#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010419 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010420#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010421#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010010422 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010423#endif /* HAVE_WAIT3 */
10424#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010010425 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010426#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010427#if defined(HAVE_WAITID) && !defined(__APPLE__)
10428 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
10429#endif
Tim Petersab034fa2002-02-01 11:27:43 +000010430#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010431 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010432#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010433#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010434 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010435#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010436#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010437 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010438#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010439#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010440 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010441#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010442#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010443 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010444#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010445#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010446 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010447#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010448 {"open", (PyCFunction)posix_open,\
10449 METH_VARARGS | METH_KEYWORDS,
10450 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010451 {"close", posix_close, METH_VARARGS, posix_close__doc__},
10452 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
10453 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
10454 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
10455 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010456#ifdef HAVE_LOCKF
10457 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
10458#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010459 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
10460 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010461#ifdef HAVE_READV
10462 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
10463#endif
10464#ifdef HAVE_PREAD
10465 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
10466#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010467 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010468#ifdef HAVE_WRITEV
10469 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
10470#endif
10471#ifdef HAVE_PWRITE
10472 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
10473#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000010474#ifdef HAVE_SENDFILE
10475 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
10476 posix_sendfile__doc__},
10477#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010010478 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010479 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010480#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010481 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010482#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010483#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020010484 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010485#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010486#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070010487 {"mkfifo", (PyCFunction)posix_mkfifo,
10488 METH_VARARGS | METH_KEYWORDS,
10489 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010490#endif
Neal Norwitz11690112002-07-30 01:08:28 +000010491#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010492 {"mknod", (PyCFunction)posix_mknod,
10493 METH_VARARGS | METH_KEYWORDS,
10494 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000010495#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010496#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000010497 {"major", posix_major, METH_VARARGS, posix_major__doc__},
10498 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
10499 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010500#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010501#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000010502 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010503#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010504#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020010505 {"truncate", (PyCFunction)posix_truncate,
10506 METH_VARARGS | METH_KEYWORDS,
10507 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010508#endif
10509#ifdef HAVE_POSIX_FALLOCATE
10510 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
10511#endif
10512#ifdef HAVE_POSIX_FADVISE
10513 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
10514#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010515#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010516 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010517#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010518#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010519 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000010520#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010521 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010522#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000010523 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010524#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010525#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010526 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010527#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010528#ifdef HAVE_SYNC
10529 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
10530#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010531#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010532 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010533#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000010534#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010535#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000010536 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000010537#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010538#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000010539 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010540#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000010541#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000010542 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010543#endif /* WIFSTOPPED */
10544#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000010545 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010546#endif /* WIFSIGNALED */
10547#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000010548 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010549#endif /* WIFEXITED */
10550#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000010551 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010552#endif /* WEXITSTATUS */
10553#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010554 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010555#endif /* WTERMSIG */
10556#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010557 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010558#endif /* WSTOPSIG */
10559#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000010560#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000010561 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010562#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000010563#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010564 {"statvfs", (PyCFunction)posix_statvfs,
10565 METH_VARARGS | METH_KEYWORDS,
10566 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010567#endif
Fred Drakec9680921999-12-13 16:37:25 +000010568#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000010569 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010570#endif
10571#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010572 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010573#endif
10574#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010575 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010576#endif
10577#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020010578 {"pathconf", (PyCFunction)posix_pathconf,
10579 METH_VARARGS | METH_KEYWORDS,
10580 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010581#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010582 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010583#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010584 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000010585 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050010586 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010587 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000010588#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000010589#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000010590 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000010591#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010010592 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010593#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010594 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010595#endif
10596#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010597 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010598#endif
10599#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010600 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010601#endif
10602#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010603 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010604#endif
10605
Benjamin Peterson9428d532011-09-14 11:45:52 -040010606#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010607 {"setxattr", (PyCFunction)posix_setxattr,
10608 METH_VARARGS | METH_KEYWORDS,
10609 posix_setxattr__doc__},
10610 {"getxattr", (PyCFunction)posix_getxattr,
10611 METH_VARARGS | METH_KEYWORDS,
10612 posix_getxattr__doc__},
10613 {"removexattr", (PyCFunction)posix_removexattr,
10614 METH_VARARGS | METH_KEYWORDS,
10615 posix_removexattr__doc__},
10616 {"listxattr", (PyCFunction)posix_listxattr,
10617 METH_VARARGS | METH_KEYWORDS,
10618 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040010619#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010620#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10621 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
10622#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010623 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010624};
10625
10626
Barry Warsaw4a342091996-12-19 23:50:02 +000010627static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010628ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000010629{
Victor Stinner8c62be82010-05-06 00:08:46 +000010630 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000010631}
10632
Brian Curtin52173d42010-12-02 18:29:18 +000010633#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000010634static int
Brian Curtin52173d42010-12-02 18:29:18 +000010635enable_symlink()
10636{
10637 HANDLE tok;
10638 TOKEN_PRIVILEGES tok_priv;
10639 LUID luid;
10640 int meth_idx = 0;
10641
10642 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000010643 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000010644
10645 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000010646 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000010647
10648 tok_priv.PrivilegeCount = 1;
10649 tok_priv.Privileges[0].Luid = luid;
10650 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
10651
10652 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
10653 sizeof(TOKEN_PRIVILEGES),
10654 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000010655 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000010656
Brian Curtin3b4499c2010-12-28 14:31:47 +000010657 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
10658 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000010659}
10660#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
10661
Barry Warsaw4a342091996-12-19 23:50:02 +000010662static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000010663all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000010664{
Guido van Rossum94f6f721999-01-06 18:42:14 +000010665#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010666 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010667#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010668#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010669 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010670#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010671#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010672 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010673#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010674#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010675 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010676#endif
Fred Drakec9680921999-12-13 16:37:25 +000010677#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010678 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000010679#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010680#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010681 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010682#endif
Fred Drake106c1a02002-04-23 15:58:02 +000010683#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000010684 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000010685#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000010686#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000010687 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010688#endif
Fred Drake106c1a02002-04-23 15:58:02 +000010689#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000010690 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000010691#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000010692#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000010693 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010694#endif
10695#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000010696 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010697#endif
10698#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000010699 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010700#endif
10701#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000010702 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010703#endif
10704#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010705 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010706#endif
10707#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000010708 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010709#endif
10710#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010711 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010712#endif
10713#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010714 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010715#endif
10716#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010717 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010718#endif
10719#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010720 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010721#endif
10722#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000010723 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010724#endif
10725#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000010726 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010727#endif
10728#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010729 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010730#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000010731#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000010732 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000010733#endif
10734#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000010735 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000010736#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020010737#ifdef O_XATTR
10738 if (ins(d, "O_XATTR", (long)O_XATTR)) return -1;
10739#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010740#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000010741 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010742#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000010743#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010744 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000010745#endif
10746#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010747 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000010748#endif
Jesus Ceacf381202012-04-24 20:44:40 +020010749#ifdef O_EXEC
10750 if (ins(d, "O_EXEC", (long)O_EXEC)) return -1;
10751#endif
10752#ifdef O_SEARCH
10753 if (ins(d, "O_SEARCH", (long)O_SEARCH)) return -1;
10754#endif
10755#ifdef O_TTY_INIT
10756 if (ins(d, "O_TTY_INIT", (long)O_TTY_INIT)) return -1;
10757#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010758#ifdef PRIO_PROCESS
10759 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
10760#endif
10761#ifdef PRIO_PGRP
10762 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
10763#endif
10764#ifdef PRIO_USER
10765 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
10766#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020010767#ifdef O_CLOEXEC
10768 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
10769#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020010770#ifdef O_ACCMODE
10771 if (ins(d, "O_ACCMODE", (long)O_ACCMODE)) return -1;
10772#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010773
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010774
Jesus Cea94363612012-06-22 18:32:07 +020010775#ifdef SEEK_HOLE
10776 if (ins(d, "SEEK_HOLE", (long)SEEK_HOLE)) return -1;
10777#endif
10778#ifdef SEEK_DATA
10779 if (ins(d, "SEEK_DATA", (long)SEEK_DATA)) return -1;
10780#endif
10781
Tim Peters5aa91602002-01-30 05:46:57 +000010782/* MS Windows */
10783#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010784 /* Don't inherit in child processes. */
10785 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010786#endif
10787#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000010788 /* Optimize for short life (keep in memory). */
10789 /* MS forgot to define this one with a non-underscore form too. */
10790 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010791#endif
10792#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000010793 /* Automatically delete when last handle is closed. */
10794 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010795#endif
10796#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000010797 /* Optimize for random access. */
10798 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010799#endif
10800#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010801 /* Optimize for sequential access. */
10802 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010803#endif
10804
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010805/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000010806#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010807 /* Send a SIGIO signal whenever input or output
10808 becomes available on file descriptor */
10809 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000010810#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010811#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010812 /* Direct disk access. */
10813 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010814#endif
10815#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000010816 /* Must be a directory. */
10817 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010818#endif
10819#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000010820 /* Do not follow links. */
10821 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010822#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020010823#ifdef O_NOLINKS
10824 /* Fails if link count of the named file is greater than 1 */
10825 if (ins(d, "O_NOLINKS", (long)O_NOLINKS)) return -1;
10826#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000010827#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010828 /* Do not update the access time. */
10829 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000010830#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000010831
Victor Stinner8c62be82010-05-06 00:08:46 +000010832 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010833#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010834 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010835#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010836#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010837 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010838#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010839#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000010840 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010841#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010842#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010843 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010844#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010845#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000010846 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010847#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010848#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000010849 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010850#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010851#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010852 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010853#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010854#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000010855 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010856#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010857#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000010858 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010859#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010860#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000010861 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010862#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010863#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000010864 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010865#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010866#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000010867 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010868#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010869#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000010870 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010871#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010872#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000010873 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010874#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010875#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010876 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010877#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010878#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010879 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010880#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010881#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000010882 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010883#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010884
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000010885 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000010886#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000010887 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000010888#endif /* ST_RDONLY */
10889#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000010890 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000010891#endif /* ST_NOSUID */
10892
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000010893 /* FreeBSD sendfile() constants */
10894#ifdef SF_NODISKIO
10895 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
10896#endif
10897#ifdef SF_MNOWAIT
10898 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
10899#endif
10900#ifdef SF_SYNC
10901 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
10902#endif
10903
Ross Lagerwall7807c352011-03-17 20:20:30 +020010904 /* constants for posix_fadvise */
10905#ifdef POSIX_FADV_NORMAL
10906 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
10907#endif
10908#ifdef POSIX_FADV_SEQUENTIAL
10909 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
10910#endif
10911#ifdef POSIX_FADV_RANDOM
10912 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
10913#endif
10914#ifdef POSIX_FADV_NOREUSE
10915 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
10916#endif
10917#ifdef POSIX_FADV_WILLNEED
10918 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
10919#endif
10920#ifdef POSIX_FADV_DONTNEED
10921 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
10922#endif
10923
10924 /* constants for waitid */
10925#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
10926 if (ins(d, "P_PID", (long)P_PID)) return -1;
10927 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
10928 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
10929#endif
10930#ifdef WEXITED
10931 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
10932#endif
10933#ifdef WNOWAIT
10934 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
10935#endif
10936#ifdef WSTOPPED
10937 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
10938#endif
10939#ifdef CLD_EXITED
10940 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
10941#endif
10942#ifdef CLD_DUMPED
10943 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
10944#endif
10945#ifdef CLD_TRAPPED
10946 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
10947#endif
10948#ifdef CLD_CONTINUED
10949 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
10950#endif
10951
10952 /* constants for lockf */
10953#ifdef F_LOCK
10954 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
10955#endif
10956#ifdef F_TLOCK
10957 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
10958#endif
10959#ifdef F_ULOCK
10960 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
10961#endif
10962#ifdef F_TEST
10963 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
10964#endif
10965
Guido van Rossum246bc171999-02-01 23:54:31 +000010966#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010967 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
10968 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
10969 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
10970 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
10971 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000010972#endif
10973
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010974#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020010975 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010976 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
10977 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
10978#ifdef SCHED_SPORADIC
10979 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
10980#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010981#ifdef SCHED_BATCH
10982 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
10983#endif
10984#ifdef SCHED_IDLE
10985 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
10986#endif
10987#ifdef SCHED_RESET_ON_FORK
10988 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
10989#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020010990#ifdef SCHED_SYS
10991 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
10992#endif
10993#ifdef SCHED_IA
10994 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
10995#endif
10996#ifdef SCHED_FSS
10997 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
10998#endif
10999#ifdef SCHED_FX
11000 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11001#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011002#endif
11003
Benjamin Peterson9428d532011-09-14 11:45:52 -040011004#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011005 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11006 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11007 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11008#endif
11009
Victor Stinner8b905bd2011-10-25 13:34:04 +020011010#ifdef RTLD_LAZY
11011 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11012#endif
11013#ifdef RTLD_NOW
11014 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11015#endif
11016#ifdef RTLD_GLOBAL
11017 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11018#endif
11019#ifdef RTLD_LOCAL
11020 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11021#endif
11022#ifdef RTLD_NODELETE
11023 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11024#endif
11025#ifdef RTLD_NOLOAD
11026 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11027#endif
11028#ifdef RTLD_DEEPBIND
11029 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11030#endif
11031
Victor Stinner8c62be82010-05-06 00:08:46 +000011032 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011033}
11034
11035
Tim Peters5aa91602002-01-30 05:46:57 +000011036#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011037#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011038#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011039
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011040#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011041#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011042#define MODNAME "posix"
11043#endif
11044
Martin v. Löwis1a214512008-06-11 05:26:20 +000011045static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011046 PyModuleDef_HEAD_INIT,
11047 MODNAME,
11048 posix__doc__,
11049 -1,
11050 posix_methods,
11051 NULL,
11052 NULL,
11053 NULL,
11054 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011055};
11056
11057
Larry Hastings9cf065c2012-06-22 16:30:09 -070011058static char *have_functions[] = {
11059
11060#ifdef HAVE_FACCESSAT
11061 "HAVE_FACCESSAT",
11062#endif
11063
11064#ifdef HAVE_FCHDIR
11065 "HAVE_FCHDIR",
11066#endif
11067
11068#ifdef HAVE_FCHMOD
11069 "HAVE_FCHMOD",
11070#endif
11071
11072#ifdef HAVE_FCHMODAT
11073 "HAVE_FCHMODAT",
11074#endif
11075
11076#ifdef HAVE_FCHOWN
11077 "HAVE_FCHOWN",
11078#endif
11079
11080#ifdef HAVE_FEXECVE
11081 "HAVE_FEXECVE",
11082#endif
11083
11084#ifdef HAVE_FDOPENDIR
11085 "HAVE_FDOPENDIR",
11086#endif
11087
Georg Brandl306336b2012-06-24 12:55:33 +020011088#ifdef HAVE_FPATHCONF
11089 "HAVE_FPATHCONF",
11090#endif
11091
Larry Hastings9cf065c2012-06-22 16:30:09 -070011092#ifdef HAVE_FSTATAT
11093 "HAVE_FSTATAT",
11094#endif
11095
11096#ifdef HAVE_FSTATVFS
11097 "HAVE_FSTATVFS",
11098#endif
11099
Georg Brandl306336b2012-06-24 12:55:33 +020011100#ifdef HAVE_FTRUNCATE
11101 "HAVE_FTRUNCATE",
11102#endif
11103
Larry Hastings9cf065c2012-06-22 16:30:09 -070011104#ifdef HAVE_FUTIMENS
11105 "HAVE_FUTIMENS",
11106#endif
11107
11108#ifdef HAVE_FUTIMES
11109 "HAVE_FUTIMES",
11110#endif
11111
11112#ifdef HAVE_FUTIMESAT
11113 "HAVE_FUTIMESAT",
11114#endif
11115
11116#ifdef HAVE_LINKAT
11117 "HAVE_LINKAT",
11118#endif
11119
11120#ifdef HAVE_LCHFLAGS
11121 "HAVE_LCHFLAGS",
11122#endif
11123
11124#ifdef HAVE_LCHMOD
11125 "HAVE_LCHMOD",
11126#endif
11127
11128#ifdef HAVE_LCHOWN
11129 "HAVE_LCHOWN",
11130#endif
11131
11132#ifdef HAVE_LSTAT
11133 "HAVE_LSTAT",
11134#endif
11135
11136#ifdef HAVE_LUTIMES
11137 "HAVE_LUTIMES",
11138#endif
11139
11140#ifdef HAVE_MKDIRAT
11141 "HAVE_MKDIRAT",
11142#endif
11143
11144#ifdef HAVE_MKFIFOAT
11145 "HAVE_MKFIFOAT",
11146#endif
11147
11148#ifdef HAVE_MKNODAT
11149 "HAVE_MKNODAT",
11150#endif
11151
11152#ifdef HAVE_OPENAT
11153 "HAVE_OPENAT",
11154#endif
11155
11156#ifdef HAVE_READLINKAT
11157 "HAVE_READLINKAT",
11158#endif
11159
11160#ifdef HAVE_RENAMEAT
11161 "HAVE_RENAMEAT",
11162#endif
11163
11164#ifdef HAVE_SYMLINKAT
11165 "HAVE_SYMLINKAT",
11166#endif
11167
11168#ifdef HAVE_UNLINKAT
11169 "HAVE_UNLINKAT",
11170#endif
11171
11172#ifdef HAVE_UTIMENSAT
11173 "HAVE_UTIMENSAT",
11174#endif
11175
11176#ifdef MS_WINDOWS
11177 "MS_WINDOWS",
11178#endif
11179
11180 NULL
11181};
11182
11183
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011184PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011185INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011186{
Victor Stinner8c62be82010-05-06 00:08:46 +000011187 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011188 PyObject *list;
11189 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000011190
Brian Curtin52173d42010-12-02 18:29:18 +000011191#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011192 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011193#endif
11194
Victor Stinner8c62be82010-05-06 00:08:46 +000011195 m = PyModule_Create(&posixmodule);
11196 if (m == NULL)
11197 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011198
Victor Stinner8c62be82010-05-06 00:08:46 +000011199 /* Initialize environ dictionary */
11200 v = convertenviron();
11201 Py_XINCREF(v);
11202 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11203 return NULL;
11204 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011205
Victor Stinner8c62be82010-05-06 00:08:46 +000011206 if (all_ins(m))
11207 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011208
Victor Stinner8c62be82010-05-06 00:08:46 +000011209 if (setup_confname_tables(m))
11210 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011211
Victor Stinner8c62be82010-05-06 00:08:46 +000011212 Py_INCREF(PyExc_OSError);
11213 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011214
Guido van Rossumb3d39562000-01-31 18:41:26 +000011215#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011216 if (posix_putenv_garbage == NULL)
11217 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011218#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011219
Victor Stinner8c62be82010-05-06 00:08:46 +000011220 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011221#if defined(HAVE_WAITID) && !defined(__APPLE__)
11222 waitid_result_desc.name = MODNAME ".waitid_result";
11223 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
11224#endif
11225
Victor Stinner8c62be82010-05-06 00:08:46 +000011226 stat_result_desc.name = MODNAME ".stat_result";
11227 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11228 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11229 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
11230 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
11231 structseq_new = StatResultType.tp_new;
11232 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011233
Victor Stinner8c62be82010-05-06 00:08:46 +000011234 statvfs_result_desc.name = MODNAME ".statvfs_result";
11235 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011236#ifdef NEED_TICKS_PER_SECOND
11237# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011238 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011239# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011240 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011241# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011242 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011243# endif
11244#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011245
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050011246#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011247 sched_param_desc.name = MODNAME ".sched_param";
11248 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
11249 SchedParamType.tp_new = sched_param_new;
11250#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011251
11252 /* initialize TerminalSize_info */
11253 PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc);
Victor Stinner8c62be82010-05-06 00:08:46 +000011254 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011255#if defined(HAVE_WAITID) && !defined(__APPLE__)
11256 Py_INCREF((PyObject*) &WaitidResultType);
11257 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
11258#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011259 Py_INCREF((PyObject*) &StatResultType);
11260 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11261 Py_INCREF((PyObject*) &StatVFSResultType);
11262 PyModule_AddObject(m, "statvfs_result",
11263 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011264
11265#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011266 Py_INCREF(&SchedParamType);
11267 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011268#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011269
Larry Hastings605a62d2012-06-24 04:33:36 -070011270 times_result_desc.name = MODNAME ".times_result";
11271 PyStructSequence_InitType(&TimesResultType, &times_result_desc);
11272 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
11273
11274 uname_result_desc.name = MODNAME ".uname_result";
11275 PyStructSequence_InitType(&UnameResultType, &uname_result_desc);
11276 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
11277
Thomas Wouters477c8d52006-05-27 19:21:47 +000011278#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000011279 /*
11280 * Step 2 of weak-linking support on Mac OS X.
11281 *
11282 * The code below removes functions that are not available on the
11283 * currently active platform.
11284 *
11285 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070011286 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000011287 * OSX 10.4.
11288 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011289#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011290 if (fstatvfs == NULL) {
11291 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
11292 return NULL;
11293 }
11294 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011295#endif /* HAVE_FSTATVFS */
11296
11297#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011298 if (statvfs == NULL) {
11299 if (PyObject_DelAttrString(m, "statvfs") == -1) {
11300 return NULL;
11301 }
11302 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011303#endif /* HAVE_STATVFS */
11304
11305# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011306 if (lchown == NULL) {
11307 if (PyObject_DelAttrString(m, "lchown") == -1) {
11308 return NULL;
11309 }
11310 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011311#endif /* HAVE_LCHOWN */
11312
11313
11314#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011315
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020011316 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011317 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
11318
Larry Hastings6fe20b32012-04-19 15:07:49 -070011319 billion = PyLong_FromLong(1000000000);
11320 if (!billion)
11321 return NULL;
11322
Larry Hastings9cf065c2012-06-22 16:30:09 -070011323 /* suppress "function not used" warnings */
11324 {
11325 int ignored;
11326 fd_specified("", -1);
11327 follow_symlinks_specified("", 1);
11328 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
11329 dir_fd_converter(Py_None, &ignored);
11330 dir_fd_unavailable(Py_None, &ignored);
11331 }
11332
11333 /*
11334 * provide list of locally available functions
11335 * so os.py can populate support_* lists
11336 */
11337 list = PyList_New(0);
11338 if (!list)
11339 return NULL;
11340 for (trace = have_functions; *trace; trace++) {
11341 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
11342 if (!unicode)
11343 return NULL;
11344 if (PyList_Append(list, unicode))
11345 return NULL;
11346 Py_DECREF(unicode);
11347 }
11348 PyModule_AddObject(m, "_have_functions", list);
11349
11350 initialized = 1;
11351
Victor Stinner8c62be82010-05-06 00:08:46 +000011352 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011353
Guido van Rossumb6775db1994-08-01 11:34:53 +000011354}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011355
11356#ifdef __cplusplus
11357}
11358#endif