blob: 1089ae399be05d034e310548881d62e91a484d5f [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 {
517 char *function_name;
518 char *argument_name;
519 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
770 * valid and throw an assertion if it isn't.
771 * 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}
Barry Warsawd58d7641998-07-23 16:14:40 +00001020static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001021posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +00001022{
Victor Stinner8c62be82010-05-06 00:08:46 +00001023 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +00001024}
1025
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001026
Mark Hammondef8b6542001-05-13 08:04:26 +00001027static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +00001028posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +00001029{
Victor Stinner77ccd6d2010-05-08 00:36:42 +00001030 PyObject *name_str, *rc;
1031 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
1032 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +00001033 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +00001034 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
1035 name_str);
1036 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +00001037 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +00001038}
1039
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001040#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001041static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001042win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001043{
Victor Stinner8c62be82010-05-06 00:08:46 +00001044 /* XXX We should pass the function name along in the future.
1045 (winreg.c also wants to pass the function name.)
1046 This would however require an additional param to the
1047 Windows error object, which is non-trivial.
1048 */
1049 errno = GetLastError();
1050 if (filename)
1051 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1052 else
1053 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001054}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001055
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001056static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001057win32_error_unicode(char* function, wchar_t* filename)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001058{
Victor Stinner8c62be82010-05-06 00:08:46 +00001059 /* XXX - see win32_error for comments on 'function' */
1060 errno = GetLastError();
1061 if (filename)
1062 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
1063 else
1064 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001065}
1066
Victor Stinnereb5657a2011-09-30 01:44:27 +02001067static PyObject *
1068win32_error_object(char* function, PyObject* filename)
1069{
1070 /* XXX - see win32_error for comments on 'function' */
1071 errno = GetLastError();
1072 if (filename)
1073 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1074 PyExc_WindowsError,
1075 errno,
1076 filename);
1077 else
1078 return PyErr_SetFromWindowsErr(errno);
1079}
1080
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001081#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001082
Larry Hastings9cf065c2012-06-22 16:30:09 -07001083/*
1084 * Some functions return Win32 errors, others only ever use posix_error
1085 * (this is for backwards compatibility with exceptions)
1086 */
1087static PyObject *
1088path_posix_error(char *function_name, path_t *path)
1089{
1090 if (path->narrow)
1091 return posix_error_with_filename(path->narrow);
1092 return posix_error();
1093}
1094
1095static PyObject *
1096path_error(char *function_name, path_t *path)
1097{
1098#ifdef MS_WINDOWS
1099 if (path->narrow)
1100 return win32_error(function_name, path->narrow);
1101 if (path->wide)
1102 return win32_error_unicode(function_name, path->wide);
1103 return win32_error(function_name, NULL);
1104#else
1105 return path_posix_error(function_name, path);
1106#endif
1107}
1108
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001109/* POSIX generic methods */
1110
Barry Warsaw53699e91996-12-10 23:23:01 +00001111static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001112posix_fildes(PyObject *fdobj, int (*func)(int))
1113{
Victor Stinner8c62be82010-05-06 00:08:46 +00001114 int fd;
1115 int res;
1116 fd = PyObject_AsFileDescriptor(fdobj);
1117 if (fd < 0)
1118 return NULL;
1119 if (!_PyVerify_fd(fd))
1120 return posix_error();
1121 Py_BEGIN_ALLOW_THREADS
1122 res = (*func)(fd);
1123 Py_END_ALLOW_THREADS
1124 if (res < 0)
1125 return posix_error();
1126 Py_INCREF(Py_None);
1127 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001128}
Guido van Rossum21142a01999-01-08 21:05:37 +00001129
1130static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +00001131posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001132{
Victor Stinner8c62be82010-05-06 00:08:46 +00001133 PyObject *opath1 = NULL;
1134 char *path1;
1135 int res;
1136 if (!PyArg_ParseTuple(args, format,
1137 PyUnicode_FSConverter, &opath1))
1138 return NULL;
1139 path1 = PyBytes_AsString(opath1);
1140 Py_BEGIN_ALLOW_THREADS
1141 res = (*func)(path1);
1142 Py_END_ALLOW_THREADS
1143 if (res < 0)
1144 return posix_error_with_allocated_filename(opath1);
1145 Py_DECREF(opath1);
1146 Py_INCREF(Py_None);
1147 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001148}
1149
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001150
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001151#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001152static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +00001153win32_1str(PyObject* args, char* func,
1154 char* format, BOOL (__stdcall *funcA)(LPCSTR),
1155 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001156{
Victor Stinner8c62be82010-05-06 00:08:46 +00001157 PyObject *uni;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001158 const char *ansi;
Victor Stinner8c62be82010-05-06 00:08:46 +00001159 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001160
Victor Stinnereb5657a2011-09-30 01:44:27 +02001161 if (PyArg_ParseTuple(args, wformat, &uni))
1162 {
1163 wchar_t *wstr = PyUnicode_AsUnicode(uni);
1164 if (wstr == NULL)
1165 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001166 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02001167 result = funcW(wstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00001168 Py_END_ALLOW_THREADS
1169 if (!result)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001170 return win32_error_object(func, uni);
Victor Stinner8c62be82010-05-06 00:08:46 +00001171 Py_INCREF(Py_None);
1172 return Py_None;
1173 }
Victor Stinnereb5657a2011-09-30 01:44:27 +02001174 PyErr_Clear();
1175
Victor Stinner8c62be82010-05-06 00:08:46 +00001176 if (!PyArg_ParseTuple(args, format, &ansi))
1177 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001178 if (win32_warn_bytes_api())
1179 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001180 Py_BEGIN_ALLOW_THREADS
1181 result = funcA(ansi);
1182 Py_END_ALLOW_THREADS
1183 if (!result)
1184 return win32_error(func, ansi);
1185 Py_INCREF(Py_None);
1186 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001187
1188}
1189
1190/* This is a reimplementation of the C library's chdir function,
1191 but one that produces Win32 errors instead of DOS error codes.
1192 chdir is essentially a wrapper around SetCurrentDirectory; however,
1193 it also needs to set "magic" environment variables indicating
1194 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001195static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001196win32_chdir(LPCSTR path)
1197{
Victor Stinner8c62be82010-05-06 00:08:46 +00001198 char new_path[MAX_PATH+1];
1199 int result;
1200 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001201
Victor Stinner8c62be82010-05-06 00:08:46 +00001202 if(!SetCurrentDirectoryA(path))
1203 return FALSE;
1204 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
1205 if (!result)
1206 return FALSE;
1207 /* In the ANSI API, there should not be any paths longer
1208 than MAX_PATH. */
1209 assert(result <= MAX_PATH+1);
1210 if (strncmp(new_path, "\\\\", 2) == 0 ||
1211 strncmp(new_path, "//", 2) == 0)
1212 /* UNC path, nothing to do. */
1213 return TRUE;
1214 env[1] = new_path[0];
1215 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001216}
1217
1218/* The Unicode version differs from the ANSI version
1219 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001220static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001221win32_wchdir(LPCWSTR path)
1222{
Victor Stinner8c62be82010-05-06 00:08:46 +00001223 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
1224 int result;
1225 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001226
Victor Stinner8c62be82010-05-06 00:08:46 +00001227 if(!SetCurrentDirectoryW(path))
1228 return FALSE;
1229 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
1230 if (!result)
1231 return FALSE;
1232 if (result > MAX_PATH+1) {
1233 new_path = malloc(result * sizeof(wchar_t));
1234 if (!new_path) {
1235 SetLastError(ERROR_OUTOFMEMORY);
1236 return FALSE;
1237 }
1238 result = GetCurrentDirectoryW(result, new_path);
1239 if (!result) {
1240 free(new_path);
1241 return FALSE;
1242 }
1243 }
1244 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1245 wcsncmp(new_path, L"//", 2) == 0)
1246 /* UNC path, nothing to do. */
1247 return TRUE;
1248 env[1] = new_path[0];
1249 result = SetEnvironmentVariableW(env, new_path);
1250 if (new_path != _new_path)
1251 free(new_path);
1252 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001253}
1254#endif
1255
Martin v. Löwis14694662006-02-03 12:54:16 +00001256#ifdef MS_WINDOWS
1257/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1258 - time stamps are restricted to second resolution
1259 - file modification times suffer from forth-and-back conversions between
1260 UTC and local time
1261 Therefore, we implement our own stat, based on the Win32 API directly.
1262*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001263#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001264
1265struct win32_stat{
1266 int st_dev;
1267 __int64 st_ino;
1268 unsigned short st_mode;
1269 int st_nlink;
1270 int st_uid;
1271 int st_gid;
1272 int st_rdev;
1273 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001274 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001275 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001276 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001277 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001278 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001279 int st_ctime_nsec;
1280};
1281
1282static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1283
1284static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001285FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001286{
Victor Stinner8c62be82010-05-06 00:08:46 +00001287 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1288 /* Cannot simply cast and dereference in_ptr,
1289 since it might not be aligned properly */
1290 __int64 in;
1291 memcpy(&in, in_ptr, sizeof(in));
1292 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001293 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001294}
1295
Thomas Wouters477c8d52006-05-27 19:21:47 +00001296static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001297time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001298{
Victor Stinner8c62be82010-05-06 00:08:46 +00001299 /* XXX endianness */
1300 __int64 out;
1301 out = time_in + secs_between_epochs;
1302 out = out * 10000000 + nsec_in / 100;
1303 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001304}
1305
Martin v. Löwis14694662006-02-03 12:54:16 +00001306/* Below, we *know* that ugo+r is 0444 */
1307#if _S_IREAD != 0400
1308#error Unsupported C library
1309#endif
1310static int
1311attributes_to_mode(DWORD attr)
1312{
Victor Stinner8c62be82010-05-06 00:08:46 +00001313 int m = 0;
1314 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1315 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1316 else
1317 m |= _S_IFREG;
1318 if (attr & FILE_ATTRIBUTE_READONLY)
1319 m |= 0444;
1320 else
1321 m |= 0666;
1322 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001323}
1324
1325static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001326attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001327{
Victor Stinner8c62be82010-05-06 00:08:46 +00001328 memset(result, 0, sizeof(*result));
1329 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1330 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1331 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1332 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1333 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001334 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001335 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001336 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1337 /* first clear the S_IFMT bits */
1338 result->st_mode ^= (result->st_mode & 0170000);
1339 /* now set the bits that make this a symlink */
1340 result->st_mode |= 0120000;
1341 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001342
Victor Stinner8c62be82010-05-06 00:08:46 +00001343 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001344}
1345
Guido van Rossumd8faa362007-04-27 19:54:29 +00001346static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001347attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001348{
Victor Stinner8c62be82010-05-06 00:08:46 +00001349 HANDLE hFindFile;
1350 WIN32_FIND_DATAA FileData;
1351 hFindFile = FindFirstFileA(pszFile, &FileData);
1352 if (hFindFile == INVALID_HANDLE_VALUE)
1353 return FALSE;
1354 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001355 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001356 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001357 info->dwFileAttributes = FileData.dwFileAttributes;
1358 info->ftCreationTime = FileData.ftCreationTime;
1359 info->ftLastAccessTime = FileData.ftLastAccessTime;
1360 info->ftLastWriteTime = FileData.ftLastWriteTime;
1361 info->nFileSizeHigh = FileData.nFileSizeHigh;
1362 info->nFileSizeLow = FileData.nFileSizeLow;
1363/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001364 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1365 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001366 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001367}
1368
1369static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001370attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001371{
Victor Stinner8c62be82010-05-06 00:08:46 +00001372 HANDLE hFindFile;
1373 WIN32_FIND_DATAW FileData;
1374 hFindFile = FindFirstFileW(pszFile, &FileData);
1375 if (hFindFile == INVALID_HANDLE_VALUE)
1376 return FALSE;
1377 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001378 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001379 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001380 info->dwFileAttributes = FileData.dwFileAttributes;
1381 info->ftCreationTime = FileData.ftCreationTime;
1382 info->ftLastAccessTime = FileData.ftLastAccessTime;
1383 info->ftLastWriteTime = FileData.ftLastWriteTime;
1384 info->nFileSizeHigh = FileData.nFileSizeHigh;
1385 info->nFileSizeLow = FileData.nFileSizeLow;
1386/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001387 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1388 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001389 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001390}
1391
Brian Curtind25aef52011-06-13 15:16:04 -05001392/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
1393static int has_GetFinalPathNameByHandle = 0;
Brian Curtind25aef52011-06-13 15:16:04 -05001394static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1395 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001396static int
Brian Curtind25aef52011-06-13 15:16:04 -05001397check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001398{
Brian Curtind25aef52011-06-13 15:16:04 -05001399 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001400 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1401 DWORD);
1402
Brian Curtind25aef52011-06-13 15:16:04 -05001403 /* only recheck */
1404 if (!has_GetFinalPathNameByHandle)
1405 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001406 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001407 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1408 "GetFinalPathNameByHandleA");
1409 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1410 "GetFinalPathNameByHandleW");
1411 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1412 Py_GetFinalPathNameByHandleW;
1413 }
1414 return has_GetFinalPathNameByHandle;
1415}
1416
1417static BOOL
1418get_target_path(HANDLE hdl, wchar_t **target_path)
1419{
1420 int buf_size, result_length;
1421 wchar_t *buf;
1422
1423 /* We have a good handle to the target, use it to determine
1424 the target path name (then we'll call lstat on it). */
1425 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1426 VOLUME_NAME_DOS);
1427 if(!buf_size)
1428 return FALSE;
1429
1430 buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001431 if (!buf) {
1432 SetLastError(ERROR_OUTOFMEMORY);
1433 return FALSE;
1434 }
1435
Brian Curtind25aef52011-06-13 15:16:04 -05001436 result_length = Py_GetFinalPathNameByHandleW(hdl,
1437 buf, buf_size, VOLUME_NAME_DOS);
1438
1439 if(!result_length) {
1440 free(buf);
1441 return FALSE;
1442 }
1443
1444 if(!CloseHandle(hdl)) {
1445 free(buf);
1446 return FALSE;
1447 }
1448
1449 buf[result_length] = 0;
1450
1451 *target_path = buf;
1452 return TRUE;
1453}
1454
1455static int
1456win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1457 BOOL traverse);
1458static int
1459win32_xstat_impl(const char *path, struct win32_stat *result,
1460 BOOL traverse)
1461{
Victor Stinner26de69d2011-06-17 15:15:38 +02001462 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001463 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001464 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001465 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001466 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001467 const char *dot;
1468
Brian Curtind25aef52011-06-13 15:16:04 -05001469 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001470 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1471 traverse reparse point. */
1472 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001473 }
1474
Brian Curtinf5e76d02010-11-24 13:14:05 +00001475 hFile = CreateFileA(
1476 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001477 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001478 0, /* share mode */
1479 NULL, /* security attributes */
1480 OPEN_EXISTING,
1481 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001482 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1483 Because of this, calls like GetFinalPathNameByHandle will return
1484 the symlink path agin and not the actual final path. */
1485 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1486 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001487 NULL);
1488
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001489 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001490 /* Either the target doesn't exist, or we don't have access to
1491 get a handle to it. If the former, we need to return an error.
1492 If the latter, we can use attributes_from_dir. */
1493 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001494 return -1;
1495 /* Could not get attributes on open file. Fall back to
1496 reading the directory. */
1497 if (!attributes_from_dir(path, &info, &reparse_tag))
1498 /* Very strange. This should not fail now */
1499 return -1;
1500 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1501 if (traverse) {
1502 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001503 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001504 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001505 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001506 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001507 } else {
1508 if (!GetFileInformationByHandle(hFile, &info)) {
1509 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001510 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001511 }
1512 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001513 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1514 return -1;
1515
1516 /* Close the outer open file handle now that we're about to
1517 reopen it with different flags. */
1518 if (!CloseHandle(hFile))
1519 return -1;
1520
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001521 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001522 /* In order to call GetFinalPathNameByHandle we need to open
1523 the file without the reparse handling flag set. */
1524 hFile2 = CreateFileA(
1525 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1526 NULL, OPEN_EXISTING,
1527 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1528 NULL);
1529 if (hFile2 == INVALID_HANDLE_VALUE)
1530 return -1;
1531
1532 if (!get_target_path(hFile2, &target_path))
1533 return -1;
1534
1535 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001536 free(target_path);
1537 return code;
1538 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001539 } else
1540 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001541 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001542 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001543
1544 /* Set S_IEXEC if it is an .exe, .bat, ... */
1545 dot = strrchr(path, '.');
1546 if (dot) {
1547 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1548 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1549 result->st_mode |= 0111;
1550 }
1551 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001552}
1553
1554static int
Brian Curtind25aef52011-06-13 15:16:04 -05001555win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1556 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001557{
1558 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001559 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001560 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001561 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001562 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001563 const wchar_t *dot;
1564
Brian Curtind25aef52011-06-13 15:16:04 -05001565 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001566 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1567 traverse reparse point. */
1568 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001569 }
1570
Brian Curtinf5e76d02010-11-24 13:14:05 +00001571 hFile = CreateFileW(
1572 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001573 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001574 0, /* share mode */
1575 NULL, /* security attributes */
1576 OPEN_EXISTING,
1577 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001578 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1579 Because of this, calls like GetFinalPathNameByHandle will return
1580 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001581 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001582 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001583 NULL);
1584
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001585 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001586 /* Either the target doesn't exist, or we don't have access to
1587 get a handle to it. If the former, we need to return an error.
1588 If the latter, we can use attributes_from_dir. */
1589 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001590 return -1;
1591 /* Could not get attributes on open file. Fall back to
1592 reading the directory. */
1593 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1594 /* Very strange. This should not fail now */
1595 return -1;
1596 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1597 if (traverse) {
1598 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001599 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001600 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001601 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001602 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001603 } else {
1604 if (!GetFileInformationByHandle(hFile, &info)) {
1605 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001606 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001607 }
1608 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001609 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1610 return -1;
1611
1612 /* Close the outer open file handle now that we're about to
1613 reopen it with different flags. */
1614 if (!CloseHandle(hFile))
1615 return -1;
1616
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001617 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001618 /* In order to call GetFinalPathNameByHandle we need to open
1619 the file without the reparse handling flag set. */
1620 hFile2 = CreateFileW(
1621 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1622 NULL, OPEN_EXISTING,
1623 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1624 NULL);
1625 if (hFile2 == INVALID_HANDLE_VALUE)
1626 return -1;
1627
1628 if (!get_target_path(hFile2, &target_path))
1629 return -1;
1630
1631 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001632 free(target_path);
1633 return code;
1634 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001635 } else
1636 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001637 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001638 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001639
1640 /* Set S_IEXEC if it is an .exe, .bat, ... */
1641 dot = wcsrchr(path, '.');
1642 if (dot) {
1643 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1644 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1645 result->st_mode |= 0111;
1646 }
1647 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001648}
1649
1650static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001651win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001652{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001653 /* Protocol violation: we explicitly clear errno, instead of
1654 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001655 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001656 errno = 0;
1657 return code;
1658}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001659
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001660static int
1661win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1662{
1663 /* Protocol violation: we explicitly clear errno, instead of
1664 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001665 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001666 errno = 0;
1667 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001668}
Brian Curtind25aef52011-06-13 15:16:04 -05001669/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001670
1671 In Posix, stat automatically traverses symlinks and returns the stat
1672 structure for the target. In Windows, the equivalent GetFileAttributes by
1673 default does not traverse symlinks and instead returns attributes for
1674 the symlink.
1675
1676 Therefore, win32_lstat will get the attributes traditionally, and
1677 win32_stat will first explicitly resolve the symlink target and then will
1678 call win32_lstat on that result.
1679
Ezio Melotti4969f702011-03-15 05:59:46 +02001680 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001681
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001682static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001683win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001684{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001685 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001686}
1687
Victor Stinner8c62be82010-05-06 00:08:46 +00001688static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001689win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001690{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001691 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001692}
1693
1694static int
1695win32_stat(const char* path, struct win32_stat *result)
1696{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001697 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001698}
1699
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001700static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001701win32_stat_w(const wchar_t* path, struct win32_stat *result)
1702{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001703 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001704}
1705
1706static int
1707win32_fstat(int file_number, struct win32_stat *result)
1708{
Victor Stinner8c62be82010-05-06 00:08:46 +00001709 BY_HANDLE_FILE_INFORMATION info;
1710 HANDLE h;
1711 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001712
Richard Oudkerk2240ac12012-07-06 12:05:32 +01001713 if (!_PyVerify_fd(file_number))
1714 h = INVALID_HANDLE_VALUE;
1715 else
1716 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001717
Victor Stinner8c62be82010-05-06 00:08:46 +00001718 /* Protocol violation: we explicitly clear errno, instead of
1719 setting it to a POSIX error. Callers should use GetLastError. */
1720 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001721
Victor Stinner8c62be82010-05-06 00:08:46 +00001722 if (h == INVALID_HANDLE_VALUE) {
1723 /* This is really a C library error (invalid file handle).
1724 We set the Win32 error to the closes one matching. */
1725 SetLastError(ERROR_INVALID_HANDLE);
1726 return -1;
1727 }
1728 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001729
Victor Stinner8c62be82010-05-06 00:08:46 +00001730 type = GetFileType(h);
1731 if (type == FILE_TYPE_UNKNOWN) {
1732 DWORD error = GetLastError();
1733 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001734 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001735 }
1736 /* else: valid but unknown file */
1737 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001738
Victor Stinner8c62be82010-05-06 00:08:46 +00001739 if (type != FILE_TYPE_DISK) {
1740 if (type == FILE_TYPE_CHAR)
1741 result->st_mode = _S_IFCHR;
1742 else if (type == FILE_TYPE_PIPE)
1743 result->st_mode = _S_IFIFO;
1744 return 0;
1745 }
1746
1747 if (!GetFileInformationByHandle(h, &info)) {
1748 return -1;
1749 }
1750
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001751 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001752 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001753 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1754 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001755}
1756
1757#endif /* MS_WINDOWS */
1758
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001759PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001760"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001761This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001762 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001763or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1764\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001765Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1766or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001767\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001768See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001769
1770static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001771 {"st_mode", "protection bits"},
1772 {"st_ino", "inode"},
1773 {"st_dev", "device"},
1774 {"st_nlink", "number of hard links"},
1775 {"st_uid", "user ID of owner"},
1776 {"st_gid", "group ID of owner"},
1777 {"st_size", "total size, in bytes"},
1778 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1779 {NULL, "integer time of last access"},
1780 {NULL, "integer time of last modification"},
1781 {NULL, "integer time of last change"},
1782 {"st_atime", "time of last access"},
1783 {"st_mtime", "time of last modification"},
1784 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001785 {"st_atime_ns", "time of last access in nanoseconds"},
1786 {"st_mtime_ns", "time of last modification in nanoseconds"},
1787 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001788#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001789 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001790#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001791#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001792 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001793#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001794#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001795 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001796#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001797#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001798 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001799#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001800#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001801 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001802#endif
1803#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001804 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001805#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001806 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001807};
1808
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001809#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001810#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001811#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001812#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001813#endif
1814
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001815#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001816#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1817#else
1818#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1819#endif
1820
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001821#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001822#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1823#else
1824#define ST_RDEV_IDX ST_BLOCKS_IDX
1825#endif
1826
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001827#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1828#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1829#else
1830#define ST_FLAGS_IDX ST_RDEV_IDX
1831#endif
1832
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001833#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001834#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001835#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001836#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001837#endif
1838
1839#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1840#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1841#else
1842#define ST_BIRTHTIME_IDX ST_GEN_IDX
1843#endif
1844
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001845static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001846 "stat_result", /* name */
1847 stat_result__doc__, /* doc */
1848 stat_result_fields,
1849 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001850};
1851
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001852PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001853"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1854This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001855 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001856or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001857\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001858See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001859
1860static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001861 {"f_bsize", },
1862 {"f_frsize", },
1863 {"f_blocks", },
1864 {"f_bfree", },
1865 {"f_bavail", },
1866 {"f_files", },
1867 {"f_ffree", },
1868 {"f_favail", },
1869 {"f_flag", },
1870 {"f_namemax",},
1871 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001872};
1873
1874static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001875 "statvfs_result", /* name */
1876 statvfs_result__doc__, /* doc */
1877 statvfs_result_fields,
1878 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001879};
1880
Ross Lagerwall7807c352011-03-17 20:20:30 +02001881#if defined(HAVE_WAITID) && !defined(__APPLE__)
1882PyDoc_STRVAR(waitid_result__doc__,
1883"waitid_result: Result from waitid.\n\n\
1884This object may be accessed either as a tuple of\n\
1885 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1886or via the attributes si_pid, si_uid, and so on.\n\
1887\n\
1888See os.waitid for more information.");
1889
1890static PyStructSequence_Field waitid_result_fields[] = {
1891 {"si_pid", },
1892 {"si_uid", },
1893 {"si_signo", },
1894 {"si_status", },
1895 {"si_code", },
1896 {0}
1897};
1898
1899static PyStructSequence_Desc waitid_result_desc = {
1900 "waitid_result", /* name */
1901 waitid_result__doc__, /* doc */
1902 waitid_result_fields,
1903 5
1904};
1905static PyTypeObject WaitidResultType;
1906#endif
1907
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001908static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001909static PyTypeObject StatResultType;
1910static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001911#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001912static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001913#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001914static newfunc structseq_new;
1915
1916static PyObject *
1917statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1918{
Victor Stinner8c62be82010-05-06 00:08:46 +00001919 PyStructSequence *result;
1920 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001921
Victor Stinner8c62be82010-05-06 00:08:46 +00001922 result = (PyStructSequence*)structseq_new(type, args, kwds);
1923 if (!result)
1924 return NULL;
1925 /* If we have been initialized from a tuple,
1926 st_?time might be set to None. Initialize it
1927 from the int slots. */
1928 for (i = 7; i <= 9; i++) {
1929 if (result->ob_item[i+3] == Py_None) {
1930 Py_DECREF(Py_None);
1931 Py_INCREF(result->ob_item[i]);
1932 result->ob_item[i+3] = result->ob_item[i];
1933 }
1934 }
1935 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001936}
1937
1938
1939
1940/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001941static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001942
1943PyDoc_STRVAR(stat_float_times__doc__,
1944"stat_float_times([newval]) -> oldval\n\n\
1945Determine whether os.[lf]stat represents time stamps as float objects.\n\
1946If newval is True, future calls to stat() return floats, if it is False,\n\
1947future calls return ints. \n\
1948If newval is omitted, return the current setting.\n");
1949
1950static PyObject*
1951stat_float_times(PyObject* self, PyObject *args)
1952{
Victor Stinner8c62be82010-05-06 00:08:46 +00001953 int newval = -1;
1954 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1955 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001956 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1957 "stat_float_times() is deprecated",
1958 1))
1959 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001960 if (newval == -1)
1961 /* Return old value */
1962 return PyBool_FromLong(_stat_float_times);
1963 _stat_float_times = newval;
1964 Py_INCREF(Py_None);
1965 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001966}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001967
Larry Hastings6fe20b32012-04-19 15:07:49 -07001968static PyObject *billion = NULL;
1969
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001970static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001971fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001972{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001973 PyObject *s = _PyLong_FromTime_t(sec);
1974 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1975 PyObject *s_in_ns = NULL;
1976 PyObject *ns_total = NULL;
1977 PyObject *float_s = NULL;
1978
1979 if (!(s && ns_fractional))
1980 goto exit;
1981
1982 s_in_ns = PyNumber_Multiply(s, billion);
1983 if (!s_in_ns)
1984 goto exit;
1985
1986 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1987 if (!ns_total)
1988 goto exit;
1989
Victor Stinner4195b5c2012-02-08 23:03:19 +01001990 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001991 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1992 if (!float_s)
1993 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001994 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001995 else {
1996 float_s = s;
1997 Py_INCREF(float_s);
1998 }
1999
2000 PyStructSequence_SET_ITEM(v, index, s);
2001 PyStructSequence_SET_ITEM(v, index+3, float_s);
2002 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2003 s = NULL;
2004 float_s = NULL;
2005 ns_total = NULL;
2006exit:
2007 Py_XDECREF(s);
2008 Py_XDECREF(ns_fractional);
2009 Py_XDECREF(s_in_ns);
2010 Py_XDECREF(ns_total);
2011 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002012}
2013
Tim Peters5aa91602002-01-30 05:46:57 +00002014/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002015 (used by posix_stat() and posix_fstat()) */
2016static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002017_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002018{
Victor Stinner8c62be82010-05-06 00:08:46 +00002019 unsigned long ansec, mnsec, cnsec;
2020 PyObject *v = PyStructSequence_New(&StatResultType);
2021 if (v == NULL)
2022 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002023
Victor Stinner8c62be82010-05-06 00:08:46 +00002024 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002025#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002026 PyStructSequence_SET_ITEM(v, 1,
2027 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002028#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002029 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002030#endif
2031#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002032 PyStructSequence_SET_ITEM(v, 2,
2033 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002034#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002035 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002036#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002037 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
2038 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
2039 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00002040#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002041 PyStructSequence_SET_ITEM(v, 6,
2042 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002043#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002044 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002045#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002046
Martin v. Löwis14694662006-02-03 12:54:16 +00002047#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002048 ansec = st->st_atim.tv_nsec;
2049 mnsec = st->st_mtim.tv_nsec;
2050 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002051#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002052 ansec = st->st_atimespec.tv_nsec;
2053 mnsec = st->st_mtimespec.tv_nsec;
2054 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002055#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002056 ansec = st->st_atime_nsec;
2057 mnsec = st->st_mtime_nsec;
2058 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002059#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002060 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002061#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002062 fill_time(v, 7, st->st_atime, ansec);
2063 fill_time(v, 8, st->st_mtime, mnsec);
2064 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002065
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002066#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002067 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2068 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002069#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002070#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002071 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2072 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002073#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002074#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002075 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2076 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002077#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002078#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002079 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2080 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002081#endif
2082#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002083 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002084 PyObject *val;
2085 unsigned long bsec,bnsec;
2086 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002087#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002088 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002089#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002090 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002091#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002092 if (_stat_float_times) {
2093 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2094 } else {
2095 val = PyLong_FromLong((long)bsec);
2096 }
2097 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2098 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002099 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002100#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002101#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002102 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2103 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002104#endif
Fred Drake699f3522000-06-29 21:12:41 +00002105
Victor Stinner8c62be82010-05-06 00:08:46 +00002106 if (PyErr_Occurred()) {
2107 Py_DECREF(v);
2108 return NULL;
2109 }
Fred Drake699f3522000-06-29 21:12:41 +00002110
Victor Stinner8c62be82010-05-06 00:08:46 +00002111 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002112}
2113
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002114/* POSIX methods */
2115
Guido van Rossum94f6f721999-01-06 18:42:14 +00002116
2117static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002118posix_do_stat(char *function_name, path_t *path,
2119 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002120{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002121 STRUCT_STAT st;
2122 int result;
2123
2124#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2125 if (follow_symlinks_specified(function_name, follow_symlinks))
2126 return NULL;
2127#endif
2128
2129 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2130 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2131 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2132 return NULL;
2133
2134 Py_BEGIN_ALLOW_THREADS
2135 if (path->fd != -1)
2136 result = FSTAT(path->fd, &st);
2137 else
2138#ifdef MS_WINDOWS
2139 if (path->wide) {
2140 if (follow_symlinks)
2141 result = win32_stat_w(path->wide, &st);
2142 else
2143 result = win32_lstat_w(path->wide, &st);
2144 }
2145 else
2146#endif
2147#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2148 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2149 result = LSTAT(path->narrow, &st);
2150 else
2151#endif
2152#ifdef HAVE_FSTATAT
2153 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2154 result = fstatat(dir_fd, path->narrow, &st,
2155 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2156 else
2157#endif
2158 result = STAT(path->narrow, &st);
2159 Py_END_ALLOW_THREADS
2160
2161 if (result != 0)
2162 return path_error("stat", path);
2163
2164 return _pystat_fromstructstat(&st);
2165}
2166
2167PyDoc_STRVAR(posix_stat__doc__,
2168"stat(path, *, dir_fd=None, follow_symlinks=True) -> stat result\n\n\
2169Perform a stat system call on the given path.\n\
2170\n\
2171path may be specified as either a string or as an open file descriptor.\n\
2172\n\
2173If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2174 and path should be relative; path will then be relative to that directory.\n\
2175 dir_fd may not be supported on your platform; if it is unavailable, using\n\
2176 it will raise a NotImplementedError.\n\
2177If follow_symlinks is False, and the last element of the path is a symbolic\n\
2178 link, stat will examine the symbolic link itself instead of the file the\n\
2179 link points to.\n\
2180It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2181 an open file descriptor.");
2182
2183static PyObject *
2184posix_stat(PyObject *self, PyObject *args, PyObject *kwargs)
2185{
2186 static char *keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2187 path_t path;
2188 int dir_fd = DEFAULT_DIR_FD;
2189 int follow_symlinks = 1;
2190 PyObject *return_value;
2191
2192 memset(&path, 0, sizeof(path));
2193 path.allow_fd = 1;
2194 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:stat", keywords,
2195 path_converter, &path,
2196#ifdef HAVE_FSTATAT
2197 dir_fd_converter, &dir_fd,
2198#else
2199 dir_fd_unavailable, &dir_fd,
2200#endif
2201 &follow_symlinks))
2202 return NULL;
2203 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2204 path_cleanup(&path);
2205 return return_value;
2206}
2207
2208PyDoc_STRVAR(posix_lstat__doc__,
2209"lstat(path, *, dir_fd=None) -> stat result\n\n\
2210Like stat(), but do not follow symbolic links.\n\
2211Equivalent to stat(path, follow_symlinks=False).");
2212
2213static PyObject *
2214posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2215{
2216 static char *keywords[] = {"path", "dir_fd", NULL};
2217 path_t path;
2218 int dir_fd = DEFAULT_DIR_FD;
2219 int follow_symlinks = 0;
2220 PyObject *return_value;
2221
2222 memset(&path, 0, sizeof(path));
2223 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2224 path_converter, &path,
2225#ifdef HAVE_FSTATAT
2226 dir_fd_converter, &dir_fd
2227#else
2228 dir_fd_unavailable, &dir_fd
2229#endif
2230 ))
2231 return NULL;
2232 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2233 path_cleanup(&path);
2234 return return_value;
2235}
2236
2237PyDoc_STRVAR(posix_access__doc__,
2238"access(path, mode, *, dir_fd=None, effective_ids=False,\
2239 follow_symlinks=True)\n\n\
2240Use the real uid/gid to test for access to a path. Returns True if granted,\n\
2241False otherwise.\n\
2242\n\
2243If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2244 and path should be relative; path will then be relative to that directory.\n\
2245If effective_ids is True, access will use the effective uid/gid instead of\n\
2246 the real uid/gid.\n\
2247If follow_symlinks is False, and the last element of the path is a symbolic\n\
2248 link, access will examine the symbolic link itself instead of the file the\n\
2249 link points to.\n\
2250dir_fd, effective_ids, and follow_symlinks may not be implemented\n\
2251 on your platform. If they are unavailable, using them will raise a\n\
2252 NotImplementedError.\n\
2253\n\
2254Note that most operations will use the effective uid/gid, therefore this\n\
2255 routine can be used in a suid/sgid environment to test if the invoking user\n\
2256 has the specified access to the path.\n\
2257The mode argument can be F_OK to test existence, or the inclusive-OR\n\
2258 of R_OK, W_OK, and X_OK.");
2259
2260static PyObject *
2261posix_access(PyObject *self, PyObject *args, PyObject *kwargs)
2262{
2263 static char *keywords[] = {"path", "mode", "dir_fd", "effective_ids",
2264 "follow_symlinks", NULL};
2265 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002266 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002267 int dir_fd = DEFAULT_DIR_FD;
2268 int effective_ids = 0;
2269 int follow_symlinks = 1;
2270 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002271
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002272#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002273 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002274#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002275 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002276#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002277
2278 memset(&path, 0, sizeof(path));
2279 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&pp:access", keywords,
2280 path_converter, &path, &mode,
2281#ifdef HAVE_FACCESSAT
2282 dir_fd_converter, &dir_fd,
2283#else
2284 dir_fd_unavailable, &dir_fd,
2285#endif
2286 &effective_ids, &follow_symlinks))
2287 return NULL;
2288
2289#ifndef HAVE_FACCESSAT
2290 if (follow_symlinks_specified("access", follow_symlinks))
2291 goto exit;
2292
2293 if (effective_ids) {
2294 argument_unavailable_error("access", "effective_ids");
2295 goto exit;
2296 }
2297#endif
2298
2299#ifdef MS_WINDOWS
2300 Py_BEGIN_ALLOW_THREADS
2301 if (path.wide != NULL)
2302 attr = GetFileAttributesW(path.wide);
2303 else
2304 attr = GetFileAttributesA(path.narrow);
2305 Py_END_ALLOW_THREADS
2306
2307 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002308 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002309 * * we didn't get a -1, and
2310 * * write access wasn't requested,
2311 * * or the file isn't read-only,
2312 * * or it's a directory.
2313 * (Directories cannot be read-only on Windows.)
2314 */
2315 return_value = PyBool_FromLong(
2316 (attr != 0xFFFFFFFF) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002317 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002318 !(attr & FILE_ATTRIBUTE_READONLY) ||
2319 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2320#else
2321
2322 Py_BEGIN_ALLOW_THREADS
2323#ifdef HAVE_FACCESSAT
2324 if ((dir_fd != DEFAULT_DIR_FD) ||
2325 effective_ids ||
2326 !follow_symlinks) {
2327 int flags = 0;
2328 if (!follow_symlinks)
2329 flags |= AT_SYMLINK_NOFOLLOW;
2330 if (effective_ids)
2331 flags |= AT_EACCESS;
2332 result = faccessat(dir_fd, path.narrow, mode, flags);
2333 }
2334 else
2335#endif
2336 result = access(path.narrow, mode);
2337 Py_END_ALLOW_THREADS
2338 return_value = PyBool_FromLong(!result);
2339#endif
2340
2341#ifndef HAVE_FACCESSAT
2342exit:
2343#endif
2344 path_cleanup(&path);
2345 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002346}
2347
Guido van Rossumd371ff11999-01-25 16:12:23 +00002348#ifndef F_OK
2349#define F_OK 0
2350#endif
2351#ifndef R_OK
2352#define R_OK 4
2353#endif
2354#ifndef W_OK
2355#define W_OK 2
2356#endif
2357#ifndef X_OK
2358#define X_OK 1
2359#endif
2360
2361#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002362PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002363"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002364Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00002365
2366static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002367posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002368{
Victor Stinner8c62be82010-05-06 00:08:46 +00002369 int id;
2370 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002371
Victor Stinner8c62be82010-05-06 00:08:46 +00002372 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
2373 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002374
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002375#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002376 /* file descriptor 0 only, the default input device (stdin) */
2377 if (id == 0) {
2378 ret = ttyname();
2379 }
2380 else {
2381 ret = NULL;
2382 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002383#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002384 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002385#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002386 if (ret == NULL)
2387 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002388 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002389}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002390#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002391
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002392#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002393PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002394"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002395Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002396
2397static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002398posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002399{
Victor Stinner8c62be82010-05-06 00:08:46 +00002400 char *ret;
2401 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002402
Greg Wardb48bc172000-03-01 21:51:56 +00002403#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002404 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002405#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002406 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002407#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002408 if (ret == NULL)
2409 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002410 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002411}
2412#endif
2413
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002414PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002415"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002416Change the current working directory to the specified path.\n\
2417\n\
2418path may always be specified as a string.\n\
2419On some platforms, path may also be specified as an open file descriptor.\n\
2420 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002421
Barry Warsaw53699e91996-12-10 23:23:01 +00002422static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002423posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002424{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002425 path_t path;
2426 int result;
2427 PyObject *return_value = NULL;
2428 static char *keywords[] = {"path", NULL};
2429
2430 memset(&path, 0, sizeof(path));
2431#ifdef HAVE_FCHDIR
2432 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002433#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002434 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2435 path_converter, &path
2436 ))
2437 return NULL;
2438
2439 Py_BEGIN_ALLOW_THREADS
2440#ifdef MS_WINDOWS
2441 if (path.wide)
2442 result = win32_wchdir(path.wide);
2443 else
2444 result = win32_chdir(path.narrow);
2445 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002446#else
2447#ifdef HAVE_FCHDIR
2448 if (path.fd != -1)
2449 result = fchdir(path.fd);
2450 else
2451#endif
2452 result = chdir(path.narrow);
2453#endif
2454 Py_END_ALLOW_THREADS
2455
2456 if (result) {
2457 return_value = path_error("chdir", &path);
2458 goto exit;
2459 }
2460
2461 return_value = Py_None;
2462 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02002463
Larry Hastings9cf065c2012-06-22 16:30:09 -07002464exit:
2465 path_cleanup(&path);
2466 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002467}
2468
Fred Drake4d1e64b2002-04-15 19:40:07 +00002469#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002470PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002471"fchdir(fd)\n\n\
2472Change to the directory of the given file descriptor. fd must be\n\
2473opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002474
2475static PyObject *
2476posix_fchdir(PyObject *self, PyObject *fdobj)
2477{
Victor Stinner8c62be82010-05-06 00:08:46 +00002478 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002479}
2480#endif /* HAVE_FCHDIR */
2481
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002482
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002483PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002484"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2485Change the access permissions of a file.\n\
2486\n\
2487path may always be specified as a string.\n\
2488On some platforms, path may also be specified as an open file descriptor.\n\
2489 If this functionality is unavailable, using it raises an exception.\n\
2490If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2491 and path should be relative; path will then be relative to that directory.\n\
2492If follow_symlinks is False, and the last element of the path is a symbolic\n\
2493 link, chmod will modify the symbolic link itself instead of the file the\n\
2494 link points to.\n\
2495It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2496 an open file descriptor.\n\
2497dir_fd and follow_symlinks may not be implemented on your platform.\n\
2498 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002499
Barry Warsaw53699e91996-12-10 23:23:01 +00002500static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002501posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002502{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002503 path_t path;
2504 int mode;
2505 int dir_fd = DEFAULT_DIR_FD;
2506 int follow_symlinks = 1;
2507 int result;
2508 PyObject *return_value = NULL;
2509 static char *keywords[] = {"path", "mode", "dir_fd",
2510 "follow_symlinks", NULL};
2511
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002512#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002513 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002514#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002515
Larry Hastings9cf065c2012-06-22 16:30:09 -07002516#ifdef HAVE_FCHMODAT
2517 int fchmodat_nofollow_unsupported = 0;
2518#endif
2519
2520 memset(&path, 0, sizeof(path));
2521#ifdef HAVE_FCHMOD
2522 path.allow_fd = 1;
2523#endif
2524 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2525 path_converter, &path,
2526 &mode,
2527#ifdef HAVE_FCHMODAT
2528 dir_fd_converter, &dir_fd,
2529#else
2530 dir_fd_unavailable, &dir_fd,
2531#endif
2532 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002533 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002534
2535#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2536 if (follow_symlinks_specified("chmod", follow_symlinks))
2537 goto exit;
2538#endif
2539
2540#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002541 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002542 if (path.wide)
2543 attr = GetFileAttributesW(path.wide);
2544 else
2545 attr = GetFileAttributesA(path.narrow);
2546 if (attr == 0xFFFFFFFF)
2547 result = 0;
2548 else {
2549 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002550 attr &= ~FILE_ATTRIBUTE_READONLY;
2551 else
2552 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002553 if (path.wide)
2554 result = SetFileAttributesW(path.wide, attr);
2555 else
2556 result = SetFileAttributesA(path.narrow, attr);
2557 }
2558 Py_END_ALLOW_THREADS
2559
2560 if (!result) {
2561 return_value = win32_error_object("chmod", path.object);
2562 goto exit;
2563 }
2564#else /* MS_WINDOWS */
2565 Py_BEGIN_ALLOW_THREADS
2566#ifdef HAVE_FCHMOD
2567 if (path.fd != -1)
2568 result = fchmod(path.fd, mode);
2569 else
2570#endif
2571#ifdef HAVE_LCHMOD
2572 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2573 result = lchmod(path.narrow, mode);
2574 else
2575#endif
2576#ifdef HAVE_FCHMODAT
2577 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2578 /*
2579 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2580 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002581 * and then says it isn't implemented yet.
2582 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002583 *
2584 * Once it is supported, os.chmod will automatically
2585 * support dir_fd and follow_symlinks=False. (Hopefully.)
2586 * Until then, we need to be careful what exception we raise.
2587 */
2588 result = fchmodat(dir_fd, path.narrow, mode,
2589 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2590 /*
2591 * But wait! We can't throw the exception without allowing threads,
2592 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2593 */
2594 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002595 result &&
2596 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2597 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002598 }
2599 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002600#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002601 result = chmod(path.narrow, mode);
2602 Py_END_ALLOW_THREADS
2603
2604 if (result) {
2605#ifdef HAVE_FCHMODAT
2606 if (fchmodat_nofollow_unsupported) {
2607 if (dir_fd != DEFAULT_DIR_FD)
2608 dir_fd_and_follow_symlinks_invalid("chmod",
2609 dir_fd, follow_symlinks);
2610 else
2611 follow_symlinks_specified("chmod", follow_symlinks);
2612 }
2613 else
2614#endif
2615 return_value = path_error("chmod", &path);
2616 goto exit;
2617 }
2618#endif
2619
2620 Py_INCREF(Py_None);
2621 return_value = Py_None;
2622exit:
2623 path_cleanup(&path);
2624 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002625}
2626
Larry Hastings9cf065c2012-06-22 16:30:09 -07002627
Christian Heimes4e30a842007-11-30 22:12:06 +00002628#ifdef HAVE_FCHMOD
2629PyDoc_STRVAR(posix_fchmod__doc__,
2630"fchmod(fd, mode)\n\n\
2631Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002632descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002633
2634static PyObject *
2635posix_fchmod(PyObject *self, PyObject *args)
2636{
Victor Stinner8c62be82010-05-06 00:08:46 +00002637 int fd, mode, res;
2638 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2639 return NULL;
2640 Py_BEGIN_ALLOW_THREADS
2641 res = fchmod(fd, mode);
2642 Py_END_ALLOW_THREADS
2643 if (res < 0)
2644 return posix_error();
2645 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002646}
2647#endif /* HAVE_FCHMOD */
2648
2649#ifdef HAVE_LCHMOD
2650PyDoc_STRVAR(posix_lchmod__doc__,
2651"lchmod(path, mode)\n\n\
2652Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002653affects the link itself rather than the target.\n\
2654Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002655
2656static PyObject *
2657posix_lchmod(PyObject *self, PyObject *args)
2658{
Victor Stinner8c62be82010-05-06 00:08:46 +00002659 PyObject *opath;
2660 char *path;
2661 int i;
2662 int res;
2663 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
2664 &opath, &i))
2665 return NULL;
2666 path = PyBytes_AsString(opath);
2667 Py_BEGIN_ALLOW_THREADS
2668 res = lchmod(path, i);
2669 Py_END_ALLOW_THREADS
2670 if (res < 0)
2671 return posix_error_with_allocated_filename(opath);
2672 Py_DECREF(opath);
2673 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002674}
2675#endif /* HAVE_LCHMOD */
2676
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002677
Thomas Wouterscf297e42007-02-23 15:07:44 +00002678#ifdef HAVE_CHFLAGS
2679PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002680"chflags(path, flags, *, follow_symlinks=True)\n\n\
2681Set file flags.\n\
2682\n\
2683If follow_symlinks is False, and the last element of the path is a symbolic\n\
2684 link, chflags will change flags on the symbolic link itself instead of the\n\
2685 file the link points to.\n\
2686follow_symlinks may not be implemented on your platform. If it is\n\
2687unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002688
2689static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002690posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00002691{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002692 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002693 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002694 int follow_symlinks = 1;
2695 int result;
2696 PyObject *return_value;
2697 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
2698
2699 memset(&path, 0, sizeof(path));
2700 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
2701 path_converter, &path,
2702 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002703 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002704
2705#ifndef HAVE_LCHFLAGS
2706 if (follow_symlinks_specified("chflags", follow_symlinks))
2707 goto exit;
2708#endif
2709
Victor Stinner8c62be82010-05-06 00:08:46 +00002710 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002711#ifdef HAVE_LCHFLAGS
2712 if (!follow_symlinks)
2713 result = lchflags(path.narrow, flags);
2714 else
2715#endif
2716 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002717 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002718
2719 if (result) {
2720 return_value = path_posix_error("chflags", &path);
2721 goto exit;
2722 }
2723
2724 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00002725 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002726
2727exit:
2728 path_cleanup(&path);
2729 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002730}
2731#endif /* HAVE_CHFLAGS */
2732
2733#ifdef HAVE_LCHFLAGS
2734PyDoc_STRVAR(posix_lchflags__doc__,
2735"lchflags(path, flags)\n\n\
2736Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002737This function will not follow symbolic links.\n\
2738Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002739
2740static PyObject *
2741posix_lchflags(PyObject *self, PyObject *args)
2742{
Victor Stinner8c62be82010-05-06 00:08:46 +00002743 PyObject *opath;
2744 char *path;
2745 unsigned long flags;
2746 int res;
2747 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2748 PyUnicode_FSConverter, &opath, &flags))
2749 return NULL;
2750 path = PyBytes_AsString(opath);
2751 Py_BEGIN_ALLOW_THREADS
2752 res = lchflags(path, flags);
2753 Py_END_ALLOW_THREADS
2754 if (res < 0)
2755 return posix_error_with_allocated_filename(opath);
2756 Py_DECREF(opath);
2757 Py_INCREF(Py_None);
2758 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002759}
2760#endif /* HAVE_LCHFLAGS */
2761
Martin v. Löwis244edc82001-10-04 22:44:26 +00002762#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002763PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002764"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002765Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002766
2767static PyObject *
2768posix_chroot(PyObject *self, PyObject *args)
2769{
Victor Stinner8c62be82010-05-06 00:08:46 +00002770 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002771}
2772#endif
2773
Guido van Rossum21142a01999-01-08 21:05:37 +00002774#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002775PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002776"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002777force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002778
2779static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002780posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002781{
Stefan Krah0e803b32010-11-26 16:16:47 +00002782 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002783}
2784#endif /* HAVE_FSYNC */
2785
Ross Lagerwall7807c352011-03-17 20:20:30 +02002786#ifdef HAVE_SYNC
2787PyDoc_STRVAR(posix_sync__doc__,
2788"sync()\n\n\
2789Force write of everything to disk.");
2790
2791static PyObject *
2792posix_sync(PyObject *self, PyObject *noargs)
2793{
2794 Py_BEGIN_ALLOW_THREADS
2795 sync();
2796 Py_END_ALLOW_THREADS
2797 Py_RETURN_NONE;
2798}
2799#endif
2800
Guido van Rossum21142a01999-01-08 21:05:37 +00002801#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002802
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002803#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002804extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2805#endif
2806
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002807PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002808"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002809force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002810 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002811
2812static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002813posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002814{
Stefan Krah0e803b32010-11-26 16:16:47 +00002815 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002816}
2817#endif /* HAVE_FDATASYNC */
2818
2819
Fredrik Lundh10723342000-07-10 16:38:09 +00002820#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002821PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002822"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
2823Change the owner and group id of path to the numeric uid and gid.\n\
2824\n\
2825path may always be specified as a string.\n\
2826On some platforms, path may also be specified as an open file descriptor.\n\
2827 If this functionality is unavailable, using it raises an exception.\n\
2828If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2829 and path should be relative; path will then be relative to that directory.\n\
2830If follow_symlinks is False, and the last element of the path is a symbolic\n\
2831 link, chown will modify the symbolic link itself instead of the file the\n\
2832 link points to.\n\
2833It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2834 an open file descriptor.\n\
2835dir_fd and follow_symlinks may not be implemented on your platform.\n\
2836 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002837
Barry Warsaw53699e91996-12-10 23:23:01 +00002838static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002839posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002840{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002841 path_t path;
2842 long uid_l, gid_l;
2843 uid_t uid;
2844 gid_t gid;
2845 int dir_fd = DEFAULT_DIR_FD;
2846 int follow_symlinks = 1;
2847 int result;
2848 PyObject *return_value = NULL;
2849 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
2850 "follow_symlinks", NULL};
2851
2852 memset(&path, 0, sizeof(path));
2853#ifdef HAVE_FCHOWN
2854 path.allow_fd = 1;
2855#endif
2856 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&ll|$O&p:chown", keywords,
2857 path_converter, &path,
2858 &uid_l, &gid_l,
2859#ifdef HAVE_FCHOWNAT
2860 dir_fd_converter, &dir_fd,
2861#else
2862 dir_fd_unavailable, &dir_fd,
2863#endif
2864 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002865 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002866
2867#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
2868 if (follow_symlinks_specified("chown", follow_symlinks))
2869 goto exit;
2870#endif
2871 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
2872 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
2873 goto exit;
2874
2875#ifdef __APPLE__
2876 /*
2877 * This is for Mac OS X 10.3, which doesn't have lchown.
2878 * (But we still have an lchown symbol because of weak-linking.)
2879 * It doesn't have fchownat either. So there's no possibility
2880 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02002881 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002882 if ((!follow_symlinks) && (lchown == NULL)) {
2883 follow_symlinks_specified("chown", follow_symlinks);
2884 goto exit;
2885 }
2886#endif
2887
Victor Stinner8c62be82010-05-06 00:08:46 +00002888 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002889 uid = (uid_t)uid_l;
2890 gid = (uid_t)gid_l;
2891#ifdef HAVE_FCHOWN
2892 if (path.fd != -1)
2893 result = fchown(path.fd, uid, gid);
2894 else
2895#endif
2896#ifdef HAVE_LCHOWN
2897 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2898 result = lchown(path.narrow, uid, gid);
2899 else
2900#endif
2901#ifdef HAVE_FCHOWNAT
2902 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
2903 result = fchownat(dir_fd, path.narrow, uid, gid,
2904 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2905 else
2906#endif
2907 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00002908 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002909
2910 if (result) {
2911 return_value = path_posix_error("chown", &path);
2912 goto exit;
2913 }
2914
2915 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00002916 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002917
2918exit:
2919 path_cleanup(&path);
2920 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002921}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002922#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002923
Christian Heimes4e30a842007-11-30 22:12:06 +00002924#ifdef HAVE_FCHOWN
2925PyDoc_STRVAR(posix_fchown__doc__,
2926"fchown(fd, uid, gid)\n\n\
2927Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002928fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002929
2930static PyObject *
2931posix_fchown(PyObject *self, PyObject *args)
2932{
Victor Stinner8c62be82010-05-06 00:08:46 +00002933 int fd;
2934 long uid, gid;
2935 int res;
Victor Stinner26de69d2011-06-17 15:15:38 +02002936 if (!PyArg_ParseTuple(args, "ill:fchown", &fd, &uid, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00002937 return NULL;
2938 Py_BEGIN_ALLOW_THREADS
2939 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2940 Py_END_ALLOW_THREADS
2941 if (res < 0)
2942 return posix_error();
2943 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002944}
2945#endif /* HAVE_FCHOWN */
2946
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002947#ifdef HAVE_LCHOWN
2948PyDoc_STRVAR(posix_lchown__doc__,
2949"lchown(path, uid, gid)\n\n\
2950Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002951This function will not follow symbolic links.\n\
2952Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002953
2954static PyObject *
2955posix_lchown(PyObject *self, PyObject *args)
2956{
Victor Stinner8c62be82010-05-06 00:08:46 +00002957 PyObject *opath;
2958 char *path;
2959 long uid, gid;
2960 int res;
2961 if (!PyArg_ParseTuple(args, "O&ll:lchown",
2962 PyUnicode_FSConverter, &opath,
2963 &uid, &gid))
2964 return NULL;
2965 path = PyBytes_AsString(opath);
2966 Py_BEGIN_ALLOW_THREADS
2967 res = lchown(path, (uid_t) uid, (gid_t) gid);
2968 Py_END_ALLOW_THREADS
2969 if (res < 0)
2970 return posix_error_with_allocated_filename(opath);
2971 Py_DECREF(opath);
2972 Py_INCREF(Py_None);
2973 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002974}
2975#endif /* HAVE_LCHOWN */
2976
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002977
Guido van Rossum36bc6801995-06-14 22:54:23 +00002978#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002979static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002980posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002981{
Victor Stinner8c62be82010-05-06 00:08:46 +00002982 char buf[1026];
2983 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002984
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002985#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002986 if (!use_bytes) {
2987 wchar_t wbuf[1026];
2988 wchar_t *wbuf2 = wbuf;
2989 PyObject *resobj;
2990 DWORD len;
2991 Py_BEGIN_ALLOW_THREADS
2992 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2993 /* If the buffer is large enough, len does not include the
2994 terminating \0. If the buffer is too small, len includes
2995 the space needed for the terminator. */
2996 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2997 wbuf2 = malloc(len * sizeof(wchar_t));
2998 if (wbuf2)
2999 len = GetCurrentDirectoryW(len, wbuf2);
3000 }
3001 Py_END_ALLOW_THREADS
3002 if (!wbuf2) {
3003 PyErr_NoMemory();
3004 return NULL;
3005 }
3006 if (!len) {
3007 if (wbuf2 != wbuf) free(wbuf2);
3008 return win32_error("getcwdu", NULL);
3009 }
3010 resobj = PyUnicode_FromWideChar(wbuf2, len);
3011 if (wbuf2 != wbuf) free(wbuf2);
3012 return resobj;
3013 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003014
3015 if (win32_warn_bytes_api())
3016 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003017#endif
3018
Victor Stinner8c62be82010-05-06 00:08:46 +00003019 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003020 res = getcwd(buf, sizeof buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003021 Py_END_ALLOW_THREADS
3022 if (res == NULL)
3023 return posix_error();
3024 if (use_bytes)
3025 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00003026 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003027}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003028
3029PyDoc_STRVAR(posix_getcwd__doc__,
3030"getcwd() -> path\n\n\
3031Return a unicode string representing the current working directory.");
3032
3033static PyObject *
3034posix_getcwd_unicode(PyObject *self)
3035{
3036 return posix_getcwd(0);
3037}
3038
3039PyDoc_STRVAR(posix_getcwdb__doc__,
3040"getcwdb() -> path\n\n\
3041Return a bytes string representing the current working directory.");
3042
3043static PyObject *
3044posix_getcwd_bytes(PyObject *self)
3045{
3046 return posix_getcwd(1);
3047}
Guido van Rossum36bc6801995-06-14 22:54:23 +00003048#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003049
Larry Hastings9cf065c2012-06-22 16:30:09 -07003050#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3051#define HAVE_LINK 1
3052#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003053
Guido van Rossumb6775db1994-08-01 11:34:53 +00003054#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003055PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003056"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3057Create a hard link to a file.\n\
3058\n\
3059If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3060 descriptor open to a directory, and the respective path string (src or dst)\n\
3061 should be relative; the path will then be relative to that directory.\n\
3062If follow_symlinks is False, and the last element of src is a symbolic\n\
3063 link, link will create a link to the symbolic link itself instead of the\n\
3064 file the link points to.\n\
3065src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3066 platform. If they are unavailable, using them will raise a\n\
3067 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003068
Barry Warsaw53699e91996-12-10 23:23:01 +00003069static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003070posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003071{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003072 path_t src, dst;
3073 int src_dir_fd = DEFAULT_DIR_FD;
3074 int dst_dir_fd = DEFAULT_DIR_FD;
3075 int follow_symlinks = 1;
3076 PyObject *return_value = NULL;
3077 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3078 "follow_symlinks", NULL};
3079#ifdef MS_WINDOWS
3080 BOOL result;
3081#else
3082 int result;
3083#endif
3084
3085 memset(&src, 0, sizeof(src));
3086 memset(&dst, 0, sizeof(dst));
3087 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3088 path_converter, &src,
3089 path_converter, &dst,
3090 dir_fd_converter, &src_dir_fd,
3091 dir_fd_converter, &dst_dir_fd,
3092 &follow_symlinks))
3093 return NULL;
3094
3095#ifndef HAVE_LINKAT
3096 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3097 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3098 goto exit;
3099 }
3100#endif
3101
3102 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3103 PyErr_SetString(PyExc_NotImplementedError,
3104 "link: src and dst must be the same type");
3105 goto exit;
3106 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003107
Brian Curtin1b9df392010-11-24 20:24:31 +00003108#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003109 Py_BEGIN_ALLOW_THREADS
3110 if (src.wide)
3111 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3112 else
3113 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3114 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003115
Larry Hastings9cf065c2012-06-22 16:30:09 -07003116 if (!result) {
3117 return_value = win32_error_object("link", dst.object);
3118 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003119 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003120#else
3121 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003122#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003123 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3124 (dst_dir_fd != DEFAULT_DIR_FD) ||
3125 (!follow_symlinks))
3126 result = linkat(src_dir_fd, src.narrow,
3127 dst_dir_fd, dst.narrow,
3128 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3129 else
3130#endif
3131 result = link(src.narrow, dst.narrow);
3132 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003133
Larry Hastings9cf065c2012-06-22 16:30:09 -07003134 if (result) {
3135 return_value = path_error("link", &dst);
3136 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003137 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003138#endif
3139
3140 return_value = Py_None;
3141 Py_INCREF(Py_None);
3142
3143exit:
3144 path_cleanup(&src);
3145 path_cleanup(&dst);
3146 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003147}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003148#endif
3149
Brian Curtin1b9df392010-11-24 20:24:31 +00003150
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003151
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003152PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastingsfdaea062012-06-25 04:42:23 -07003153"listdir(path='.') -> list_of_filenames\n\n\
3154Return a list containing the names of the files in the directory.\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003155The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003156entries '.' and '..' even if they are present in the directory.\n\
3157\n\
Larry Hastingsfdaea062012-06-25 04:42:23 -07003158path can be specified as either str or bytes. If path is bytes,\n\
3159 the filenames returned will also be bytes; in all other circumstances\n\
3160 the filenames returned will be str.\n\
3161On some platforms, path may also be specified as an open file descriptor;\n\
3162 the file descriptor must refer to a directory.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003163 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003164
Barry Warsaw53699e91996-12-10 23:23:01 +00003165static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003166posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003167{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003168 path_t path;
3169 PyObject *list = NULL;
3170 static char *keywords[] = {"path", NULL};
3171 int fd = -1;
3172
3173#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3174 PyObject *v;
3175 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3176 BOOL result;
3177 WIN32_FIND_DATA FileData;
3178 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
3179 char *bufptr = namebuf;
3180 /* only claim to have space for MAX_PATH */
3181 Py_ssize_t len = sizeof(namebuf)-5;
3182 PyObject *po = NULL;
3183 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003184#else
3185 PyObject *v;
3186 DIR *dirp = NULL;
3187 struct dirent *ep;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003188 int return_str; /* if false, return bytes */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003189#endif
3190
3191 memset(&path, 0, sizeof(path));
3192 path.nullable = 1;
3193#ifdef HAVE_FDOPENDIR
3194 path.allow_fd = 1;
3195 path.fd = -1;
3196#endif
3197 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3198 path_converter, &path
3199 ))
3200 return NULL;
3201
Victor Stinner8c62be82010-05-06 00:08:46 +00003202 /* XXX Should redo this putting the (now four) versions of opendir
3203 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003204#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003205 if (!path.narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003206 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003207 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003208
Larry Hastings9cf065c2012-06-22 16:30:09 -07003209 if (!path.wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003210 po_wchars = L".";
3211 len = 1;
3212 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003213 po_wchars = path.wide;
3214 len = wcslen(path.wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003215 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003216 /* The +5 is so we can append "\\*.*\0" */
Victor Stinner8c62be82010-05-06 00:08:46 +00003217 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
3218 if (!wnamebuf) {
3219 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003220 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003221 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003222 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003223 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003224 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00003225 if (wch != L'/' && wch != L'\\' && wch != L':')
3226 wnamebuf[len++] = L'\\';
3227 wcscpy(wnamebuf + len, L"*.*");
3228 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003229 if ((list = PyList_New(0)) == NULL) {
3230 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003231 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003232 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003233 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003234 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003235 if (hFindFile == INVALID_HANDLE_VALUE) {
3236 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003237 if (error == ERROR_FILE_NOT_FOUND)
3238 goto exit;
3239 Py_DECREF(list);
3240 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003241 win32_error_unicode("FindFirstFileW", wnamebuf);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003242 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003243 }
3244 do {
3245 /* Skip over . and .. */
3246 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3247 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003248 v = PyUnicode_FromWideChar(wFileData.cFileName,
3249 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003250 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003251 Py_DECREF(list);
3252 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003253 break;
3254 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003255 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003256 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003257 Py_DECREF(list);
3258 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003259 break;
3260 }
3261 Py_DECREF(v);
3262 }
3263 Py_BEGIN_ALLOW_THREADS
3264 result = FindNextFileW(hFindFile, &wFileData);
3265 Py_END_ALLOW_THREADS
3266 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3267 it got to the end of the directory. */
3268 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003269 Py_DECREF(list);
3270 list = win32_error_unicode("FindNextFileW", wnamebuf);
3271 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003272 }
3273 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003274
Larry Hastings9cf065c2012-06-22 16:30:09 -07003275 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003276 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003277 strcpy(namebuf, path.narrow);
3278 len = path.length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003279 if (len > 0) {
3280 char ch = namebuf[len-1];
3281 if (ch != SEP && ch != ALTSEP && ch != ':')
3282 namebuf[len++] = '/';
3283 strcpy(namebuf + len, "*.*");
3284 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003285
Larry Hastings9cf065c2012-06-22 16:30:09 -07003286 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003287 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003288
Antoine Pitroub73caab2010-08-09 23:39:31 +00003289 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003290 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003291 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003292 if (hFindFile == INVALID_HANDLE_VALUE) {
3293 int error = GetLastError();
3294 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003295 goto exit;
3296 Py_DECREF(list);
3297 list = win32_error("FindFirstFile", namebuf);
3298 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003299 }
3300 do {
3301 /* Skip over . and .. */
3302 if (strcmp(FileData.cFileName, ".") != 0 &&
3303 strcmp(FileData.cFileName, "..") != 0) {
3304 v = PyBytes_FromString(FileData.cFileName);
3305 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003306 Py_DECREF(list);
3307 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003308 break;
3309 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003310 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003311 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003312 Py_DECREF(list);
3313 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003314 break;
3315 }
3316 Py_DECREF(v);
3317 }
3318 Py_BEGIN_ALLOW_THREADS
3319 result = FindNextFile(hFindFile, &FileData);
3320 Py_END_ALLOW_THREADS
3321 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3322 it got to the end of the directory. */
3323 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003324 Py_DECREF(list);
3325 list = win32_error("FindNextFile", namebuf);
3326 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003327 }
3328 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003329
Larry Hastings9cf065c2012-06-22 16:30:09 -07003330exit:
3331 if (hFindFile != INVALID_HANDLE_VALUE) {
3332 if (FindClose(hFindFile) == FALSE) {
3333 if (list != NULL) {
3334 Py_DECREF(list);
3335 list = win32_error_object("FindClose", path.object);
3336 }
3337 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003338 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003339 if (wnamebuf)
3340 free(wnamebuf);
3341 path_cleanup(&path);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003342
Larry Hastings9cf065c2012-06-22 16:30:09 -07003343 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003344
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003345#else
Just van Rossum96b1c902003-03-03 17:32:15 +00003346
Victor Stinner8c62be82010-05-06 00:08:46 +00003347 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003348#ifdef HAVE_FDOPENDIR
3349 if (path.fd != -1) {
3350 /* closedir() closes the FD, so we duplicate it */
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003351 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003352 fd = dup(path.fd);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003353 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003354
3355 if (fd == -1) {
3356 list = posix_error();
3357 goto exit;
3358 }
3359
Larry Hastingsfdaea062012-06-25 04:42:23 -07003360 return_str = 1;
3361
Larry Hastings9cf065c2012-06-22 16:30:09 -07003362 Py_BEGIN_ALLOW_THREADS
3363 dirp = fdopendir(fd);
3364 Py_END_ALLOW_THREADS
3365 }
3366 else
3367#endif
3368 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003369 char *name;
3370 if (path.narrow) {
3371 name = path.narrow;
3372 /* only return bytes if they specified a bytes object */
3373 return_str = !(PyBytes_Check(path.object));
3374 }
3375 else {
3376 name = ".";
3377 return_str = 1;
3378 }
3379
Larry Hastings9cf065c2012-06-22 16:30:09 -07003380 Py_BEGIN_ALLOW_THREADS
3381 dirp = opendir(name);
3382 Py_END_ALLOW_THREADS
3383 }
3384
3385 if (dirp == NULL) {
3386 list = path_error("listdir", &path);
3387 goto exit;
3388 }
3389 if ((list = PyList_New(0)) == NULL) {
3390 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003391 }
3392 for (;;) {
3393 errno = 0;
3394 Py_BEGIN_ALLOW_THREADS
3395 ep = readdir(dirp);
3396 Py_END_ALLOW_THREADS
3397 if (ep == NULL) {
3398 if (errno == 0) {
3399 break;
3400 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003401 Py_DECREF(list);
3402 list = path_error("listdir", &path);
3403 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003404 }
3405 }
3406 if (ep->d_name[0] == '.' &&
3407 (NAMLEN(ep) == 1 ||
3408 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3409 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003410 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003411 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3412 else
3413 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003414 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003415 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003416 break;
3417 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003418 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003419 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003420 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003421 break;
3422 }
3423 Py_DECREF(v);
3424 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003425
Larry Hastings9cf065c2012-06-22 16:30:09 -07003426exit:
3427 if (dirp != NULL) {
3428 Py_BEGIN_ALLOW_THREADS
3429 if (fd > -1)
3430 rewinddir(dirp);
3431 closedir(dirp);
3432 Py_END_ALLOW_THREADS
3433 }
3434
3435 path_cleanup(&path);
3436
3437 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003438
Tim Peters0bb44a42000-09-15 07:44:49 +00003439#endif /* which OS */
3440} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003441
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003442#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003443/* A helper function for abspath on win32 */
3444static PyObject *
3445posix__getfullpathname(PyObject *self, PyObject *args)
3446{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003447 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003448 char outbuf[MAX_PATH*2];
3449 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003450 PyObject *po;
3451
3452 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3453 {
3454 wchar_t *wpath;
3455 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3456 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003457 DWORD result;
3458 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003459
3460 wpath = PyUnicode_AsUnicode(po);
3461 if (wpath == NULL)
3462 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003463 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003464 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003465 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003466 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003467 woutbufp = malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003468 if (!woutbufp)
3469 return PyErr_NoMemory();
3470 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3471 }
3472 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003473 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003474 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003475 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003476 if (woutbufp != woutbuf)
3477 free(woutbufp);
3478 return v;
3479 }
3480 /* Drop the argument parsing error as narrow strings
3481 are also valid. */
3482 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003483
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003484 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3485 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003486 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003487 if (win32_warn_bytes_api())
3488 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003489 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003490 outbuf, &temp)) {
3491 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003492 return NULL;
3493 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003494 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3495 return PyUnicode_Decode(outbuf, strlen(outbuf),
3496 Py_FileSystemDefaultEncoding, NULL);
3497 }
3498 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003499} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003500
Brian Curtind25aef52011-06-13 15:16:04 -05003501
Brian Curtinf5e76d02010-11-24 13:14:05 +00003502
Brian Curtind40e6f72010-07-08 21:39:08 +00003503/* A helper function for samepath on windows */
3504static PyObject *
3505posix__getfinalpathname(PyObject *self, PyObject *args)
3506{
3507 HANDLE hFile;
3508 int buf_size;
3509 wchar_t *target_path;
3510 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003511 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003512 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003513
Victor Stinnereb5657a2011-09-30 01:44:27 +02003514 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003515 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003516 path = PyUnicode_AsUnicode(po);
3517 if (path == NULL)
3518 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003519
3520 if(!check_GetFinalPathNameByHandle()) {
3521 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3522 NotImplementedError. */
3523 return PyErr_Format(PyExc_NotImplementedError,
3524 "GetFinalPathNameByHandle not available on this platform");
3525 }
3526
3527 hFile = CreateFileW(
3528 path,
3529 0, /* desired access */
3530 0, /* share mode */
3531 NULL, /* security attributes */
3532 OPEN_EXISTING,
3533 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3534 FILE_FLAG_BACKUP_SEMANTICS,
3535 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003536
Victor Stinnereb5657a2011-09-30 01:44:27 +02003537 if(hFile == INVALID_HANDLE_VALUE)
3538 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003539
3540 /* We have a good handle to the target, use it to determine the
3541 target path name. */
3542 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3543
3544 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003545 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003546
3547 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
3548 if(!target_path)
3549 return PyErr_NoMemory();
3550
3551 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3552 buf_size, VOLUME_NAME_DOS);
3553 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003554 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003555
3556 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003557 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003558
3559 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003560 result = PyUnicode_FromWideChar(target_path, result_length);
Brian Curtind40e6f72010-07-08 21:39:08 +00003561 free(target_path);
3562 return result;
3563
3564} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003565
3566static PyObject *
3567posix__getfileinformation(PyObject *self, PyObject *args)
3568{
3569 HANDLE hFile;
3570 BY_HANDLE_FILE_INFORMATION info;
3571 int fd;
3572
3573 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
3574 return NULL;
3575
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003576 if (!_PyVerify_fd(fd))
3577 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003578
3579 hFile = (HANDLE)_get_osfhandle(fd);
3580 if (hFile == INVALID_HANDLE_VALUE)
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003581 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003582
3583 if (!GetFileInformationByHandle(hFile, &info))
3584 return win32_error("_getfileinformation", NULL);
3585
3586 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
3587 info.nFileIndexHigh,
3588 info.nFileIndexLow);
3589}
Brian Curtin9c669cc2011-06-08 18:17:18 -05003590
Brian Curtin95d028f2011-06-09 09:10:38 -05003591PyDoc_STRVAR(posix__isdir__doc__,
3592"Return true if the pathname refers to an existing directory.");
3593
Brian Curtin9c669cc2011-06-08 18:17:18 -05003594static PyObject *
3595posix__isdir(PyObject *self, PyObject *args)
3596{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003597 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003598 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003599 DWORD attributes;
3600
3601 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003602 wchar_t *wpath = PyUnicode_AsUnicode(po);
3603 if (wpath == NULL)
3604 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003605
3606 attributes = GetFileAttributesW(wpath);
3607 if (attributes == INVALID_FILE_ATTRIBUTES)
3608 Py_RETURN_FALSE;
3609 goto check;
3610 }
3611 /* Drop the argument parsing error as narrow strings
3612 are also valid. */
3613 PyErr_Clear();
3614
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003615 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003616 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003617 if (win32_warn_bytes_api())
3618 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003619 attributes = GetFileAttributesA(path);
3620 if (attributes == INVALID_FILE_ATTRIBUTES)
3621 Py_RETURN_FALSE;
3622
3623check:
3624 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3625 Py_RETURN_TRUE;
3626 else
3627 Py_RETURN_FALSE;
3628}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003629#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003630
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003631PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003632"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3633Create a directory.\n\
3634\n\
3635If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3636 and path should be relative; path will then be relative to that directory.\n\
3637dir_fd may not be implemented on your platform.\n\
3638 If it is unavailable, using it will raise a NotImplementedError.\n\
3639\n\
3640The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003641
Barry Warsaw53699e91996-12-10 23:23:01 +00003642static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003643posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003644{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003645 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003646 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003647 int dir_fd = DEFAULT_DIR_FD;
3648 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
3649 PyObject *return_value = NULL;
3650 int result;
3651
3652 memset(&path, 0, sizeof(path));
3653 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
3654 path_converter, &path, &mode,
3655#ifdef HAVE_MKDIRAT
3656 dir_fd_converter, &dir_fd
3657#else
3658 dir_fd_unavailable, &dir_fd
3659#endif
3660 ))
3661 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003662
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003663#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003664 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003665 if (path.wide)
3666 result = CreateDirectoryW(path.wide, NULL);
3667 else
3668 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003669 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003670
Larry Hastings9cf065c2012-06-22 16:30:09 -07003671 if (!result) {
3672 return_value = win32_error_object("mkdir", path.object);
3673 goto exit;
3674 }
3675#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003676 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003677#if HAVE_MKDIRAT
3678 if (dir_fd != DEFAULT_DIR_FD)
3679 result = mkdirat(dir_fd, path.narrow, mode);
3680 else
3681#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003682#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003683 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003684#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003685 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003686#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003687 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003688 if (result < 0) {
3689 return_value = path_error("mkdir", &path);
3690 goto exit;
3691 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00003692#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003693 return_value = Py_None;
3694 Py_INCREF(Py_None);
3695exit:
3696 path_cleanup(&path);
3697 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003698}
3699
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003700
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003701/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3702#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003703#include <sys/resource.h>
3704#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003705
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003706
3707#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003708PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003709"nice(inc) -> new_priority\n\n\
3710Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003711
Barry Warsaw53699e91996-12-10 23:23:01 +00003712static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003713posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00003714{
Victor Stinner8c62be82010-05-06 00:08:46 +00003715 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00003716
Victor Stinner8c62be82010-05-06 00:08:46 +00003717 if (!PyArg_ParseTuple(args, "i:nice", &increment))
3718 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003719
Victor Stinner8c62be82010-05-06 00:08:46 +00003720 /* There are two flavours of 'nice': one that returns the new
3721 priority (as required by almost all standards out there) and the
3722 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3723 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003724
Victor Stinner8c62be82010-05-06 00:08:46 +00003725 If we are of the nice family that returns the new priority, we
3726 need to clear errno before the call, and check if errno is filled
3727 before calling posix_error() on a returnvalue of -1, because the
3728 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003729
Victor Stinner8c62be82010-05-06 00:08:46 +00003730 errno = 0;
3731 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003732#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003733 if (value == 0)
3734 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003735#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003736 if (value == -1 && errno != 0)
3737 /* either nice() or getpriority() returned an error */
3738 return posix_error();
3739 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003740}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003741#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003742
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003743
3744#ifdef HAVE_GETPRIORITY
3745PyDoc_STRVAR(posix_getpriority__doc__,
3746"getpriority(which, who) -> current_priority\n\n\
3747Get program scheduling priority.");
3748
3749static PyObject *
3750posix_getpriority(PyObject *self, PyObject *args)
3751{
3752 int which, who, retval;
3753
3754 if (!PyArg_ParseTuple(args, "ii", &which, &who))
3755 return NULL;
3756 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003757 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003758 if (errno != 0)
3759 return posix_error();
3760 return PyLong_FromLong((long)retval);
3761}
3762#endif /* HAVE_GETPRIORITY */
3763
3764
3765#ifdef HAVE_SETPRIORITY
3766PyDoc_STRVAR(posix_setpriority__doc__,
3767"setpriority(which, who, prio) -> None\n\n\
3768Set program scheduling priority.");
3769
3770static PyObject *
3771posix_setpriority(PyObject *self, PyObject *args)
3772{
3773 int which, who, prio, retval;
3774
3775 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
3776 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003777 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003778 if (retval == -1)
3779 return posix_error();
3780 Py_RETURN_NONE;
3781}
3782#endif /* HAVE_SETPRIORITY */
3783
3784
Barry Warsaw53699e91996-12-10 23:23:01 +00003785static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003786internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003787{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003788 char *function_name = is_replace ? "replace" : "rename";
3789 path_t src;
3790 path_t dst;
3791 int src_dir_fd = DEFAULT_DIR_FD;
3792 int dst_dir_fd = DEFAULT_DIR_FD;
3793 int dir_fd_specified;
3794 PyObject *return_value = NULL;
3795 char format[24];
3796 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
3797
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003798#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003799 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003800 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003801#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003802 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003803#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003804
3805 memset(&src, 0, sizeof(src));
3806 memset(&dst, 0, sizeof(dst));
3807 strcpy(format, "O&O&|$O&O&:");
3808 strcat(format, function_name);
3809 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
3810 path_converter, &src,
3811 path_converter, &dst,
3812 dir_fd_converter, &src_dir_fd,
3813 dir_fd_converter, &dst_dir_fd))
3814 return NULL;
3815
3816 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
3817 (dst_dir_fd != DEFAULT_DIR_FD);
3818#ifndef HAVE_RENAMEAT
3819 if (dir_fd_specified) {
3820 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
3821 goto exit;
3822 }
3823#endif
3824
3825 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3826 PyErr_Format(PyExc_ValueError,
3827 "%s: src and dst must be the same type", function_name);
3828 goto exit;
3829 }
3830
3831#ifdef MS_WINDOWS
3832 Py_BEGIN_ALLOW_THREADS
3833 if (src.wide)
3834 result = MoveFileExW(src.wide, dst.wide, flags);
3835 else
3836 result = MoveFileExA(src.narrow, dst.narrow, flags);
3837 Py_END_ALLOW_THREADS
3838
3839 if (!result) {
3840 return_value = win32_error_object(function_name, dst.object);
3841 goto exit;
3842 }
3843
3844#else
3845 Py_BEGIN_ALLOW_THREADS
3846#ifdef HAVE_RENAMEAT
3847 if (dir_fd_specified)
3848 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
3849 else
3850#endif
3851 result = rename(src.narrow, dst.narrow);
3852 Py_END_ALLOW_THREADS
3853
3854 if (result) {
3855 return_value = path_error(function_name, &dst);
3856 goto exit;
3857 }
3858#endif
3859
3860 Py_INCREF(Py_None);
3861 return_value = Py_None;
3862exit:
3863 path_cleanup(&src);
3864 path_cleanup(&dst);
3865 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003866}
3867
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003868PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003869"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
3870Rename a file or directory.\n\
3871\n\
3872If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3873 descriptor open to a directory, and the respective path string (src or dst)\n\
3874 should be relative; the path will then be relative to that directory.\n\
3875src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
3876 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003877
3878static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003879posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003880{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003881 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003882}
3883
3884PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003885"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
3886Rename a file or directory, overwriting the destination.\n\
3887\n\
3888If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3889 descriptor open to a directory, and the respective path string (src or dst)\n\
3890 should be relative; the path will then be relative to that directory.\n\
3891src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
3892 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003893
3894static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003895posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003896{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003897 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003898}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003899
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003900PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003901"rmdir(path, *, dir_fd=None)\n\n\
3902Remove a directory.\n\
3903\n\
3904If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3905 and path should be relative; path will then be relative to that directory.\n\
3906dir_fd may not be implemented on your platform.\n\
3907 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003908
Barry Warsaw53699e91996-12-10 23:23:01 +00003909static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003910posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003911{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003912 path_t path;
3913 int dir_fd = DEFAULT_DIR_FD;
3914 static char *keywords[] = {"path", "dir_fd", NULL};
3915 int result;
3916 PyObject *return_value = NULL;
3917
3918 memset(&path, 0, sizeof(path));
3919 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
3920 path_converter, &path,
3921#ifdef HAVE_UNLINKAT
3922 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003923#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003924 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003925#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003926 ))
3927 return NULL;
3928
3929 Py_BEGIN_ALLOW_THREADS
3930#ifdef MS_WINDOWS
3931 if (path.wide)
3932 result = RemoveDirectoryW(path.wide);
3933 else
3934 result = RemoveDirectoryA(path.narrow);
3935 result = !result; /* Windows, success=1, UNIX, success=0 */
3936#else
3937#ifdef HAVE_UNLINKAT
3938 if (dir_fd != DEFAULT_DIR_FD)
3939 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
3940 else
3941#endif
3942 result = rmdir(path.narrow);
3943#endif
3944 Py_END_ALLOW_THREADS
3945
3946 if (result) {
3947 return_value = path_error("rmdir", &path);
3948 goto exit;
3949 }
3950
3951 return_value = Py_None;
3952 Py_INCREF(Py_None);
3953
3954exit:
3955 path_cleanup(&path);
3956 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003957}
3958
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003959
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003960#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003961PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003962"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003963Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003964
Barry Warsaw53699e91996-12-10 23:23:01 +00003965static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003966posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003967{
Victor Stinner8c62be82010-05-06 00:08:46 +00003968 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00003969#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003970 wchar_t *command;
3971 if (!PyArg_ParseTuple(args, "u:system", &command))
3972 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003973
Victor Stinner8c62be82010-05-06 00:08:46 +00003974 Py_BEGIN_ALLOW_THREADS
3975 sts = _wsystem(command);
3976 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00003977#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003978 PyObject *command_obj;
3979 char *command;
3980 if (!PyArg_ParseTuple(args, "O&:system",
3981 PyUnicode_FSConverter, &command_obj))
3982 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003983
Victor Stinner8c62be82010-05-06 00:08:46 +00003984 command = PyBytes_AsString(command_obj);
3985 Py_BEGIN_ALLOW_THREADS
3986 sts = system(command);
3987 Py_END_ALLOW_THREADS
3988 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00003989#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003990 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003991}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003992#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003993
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003994
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003995PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003996"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003997Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003998
Barry Warsaw53699e91996-12-10 23:23:01 +00003999static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004000posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004001{
Victor Stinner8c62be82010-05-06 00:08:46 +00004002 int i;
4003 if (!PyArg_ParseTuple(args, "i:umask", &i))
4004 return NULL;
4005 i = (int)umask(i);
4006 if (i < 0)
4007 return posix_error();
4008 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004009}
4010
Brian Curtind40e6f72010-07-08 21:39:08 +00004011#ifdef MS_WINDOWS
4012
4013/* override the default DeleteFileW behavior so that directory
4014symlinks can be removed with this function, the same as with
4015Unix symlinks */
4016BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4017{
4018 WIN32_FILE_ATTRIBUTE_DATA info;
4019 WIN32_FIND_DATAW find_data;
4020 HANDLE find_data_handle;
4021 int is_directory = 0;
4022 int is_link = 0;
4023
4024 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4025 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004026
Brian Curtind40e6f72010-07-08 21:39:08 +00004027 /* Get WIN32_FIND_DATA structure for the path to determine if
4028 it is a symlink */
4029 if(is_directory &&
4030 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4031 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4032
4033 if(find_data_handle != INVALID_HANDLE_VALUE) {
4034 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4035 FindClose(find_data_handle);
4036 }
4037 }
4038 }
4039
4040 if (is_directory && is_link)
4041 return RemoveDirectoryW(lpFileName);
4042
4043 return DeleteFileW(lpFileName);
4044}
4045#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004046
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004047PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004048"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004049Remove a file (same as remove()).\n\
4050\n\
4051If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4052 and path should be relative; path will then be relative to that directory.\n\
4053dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004054 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004055
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004056PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004057"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004058Remove a file (same as unlink()).\n\
4059\n\
4060If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4061 and path should be relative; path will then be relative to that directory.\n\
4062dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004063 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004064
Barry Warsaw53699e91996-12-10 23:23:01 +00004065static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004066posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004067{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004068 path_t path;
4069 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004070 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004071 int result;
4072 PyObject *return_value = NULL;
4073
4074 memset(&path, 0, sizeof(path));
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004075 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004076 path_converter, &path,
4077#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004078 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004079#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004080 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004081#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004082 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004083 return NULL;
4084
4085 Py_BEGIN_ALLOW_THREADS
4086#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004087 if (path.wide)
4088 result = Py_DeleteFileW(path.wide);
4089 else
4090 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004091 result = !result; /* Windows, success=1, UNIX, success=0 */
4092#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004093#ifdef HAVE_UNLINKAT
4094 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004095 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004096 else
4097#endif /* HAVE_UNLINKAT */
4098 result = unlink(path.narrow);
4099#endif
4100 Py_END_ALLOW_THREADS
4101
4102 if (result) {
4103 return_value = path_error("unlink", &path);
4104 goto exit;
4105 }
4106
4107 return_value = Py_None;
4108 Py_INCREF(Py_None);
4109
4110exit:
4111 path_cleanup(&path);
4112 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004113}
4114
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004115
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004116PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004117"uname() -> uname_result\n\n\
4118Return an object identifying the current operating system.\n\
4119The object behaves like a named tuple with the following fields:\n\
4120 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004121
Larry Hastings605a62d2012-06-24 04:33:36 -07004122static PyStructSequence_Field uname_result_fields[] = {
4123 {"sysname", "operating system name"},
4124 {"nodename", "name of machine on network (implementation-defined)"},
4125 {"release", "operating system release"},
4126 {"version", "operating system version"},
4127 {"machine", "hardware identifier"},
4128 {NULL}
4129};
4130
4131PyDoc_STRVAR(uname_result__doc__,
4132"uname_result: Result from os.uname().\n\n\
4133This object may be accessed either as a tuple of\n\
4134 (sysname, nodename, release, version, machine),\n\
4135or via the attributes sysname, nodename, release, version, and machine.\n\
4136\n\
4137See os.uname for more information.");
4138
4139static PyStructSequence_Desc uname_result_desc = {
4140 "uname_result", /* name */
4141 uname_result__doc__, /* doc */
4142 uname_result_fields,
4143 5
4144};
4145
4146static PyTypeObject UnameResultType;
4147
4148
4149#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004150static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004151posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004152{
Victor Stinner8c62be82010-05-06 00:08:46 +00004153 struct utsname u;
4154 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004155 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004156
Victor Stinner8c62be82010-05-06 00:08:46 +00004157 Py_BEGIN_ALLOW_THREADS
4158 res = uname(&u);
4159 Py_END_ALLOW_THREADS
4160 if (res < 0)
4161 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004162
4163 value = PyStructSequence_New(&UnameResultType);
4164 if (value == NULL)
4165 return NULL;
4166
4167#define SET(i, field) \
4168 { \
4169 PyObject *o = PyUnicode_DecodeASCII(field, strlen(field), NULL); \
4170 if (!o) { \
4171 Py_DECREF(value); \
4172 return NULL; \
4173 } \
4174 PyStructSequence_SET_ITEM(value, i, o); \
4175 } \
4176
4177 SET(0, u.sysname);
4178 SET(1, u.nodename);
4179 SET(2, u.release);
4180 SET(3, u.version);
4181 SET(4, u.machine);
4182
4183#undef SET
4184
4185 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004186}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004187#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004188
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004189
Larry Hastings9cf065c2012-06-22 16:30:09 -07004190PyDoc_STRVAR(posix_utime__doc__,
4191"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4192Set the access and modified time of path.\n\
4193\n\
4194path may always be specified as a string.\n\
4195On some platforms, path may also be specified as an open file descriptor.\n\
4196 If this functionality is unavailable, using it raises an exception.\n\
4197\n\
4198If times is not None, it must be a tuple (atime, mtime);\n\
4199 atime and mtime should be expressed as float seconds since the epoch.\n\
4200If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4201 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4202 since the epoch.\n\
4203If both times and ns are None, utime uses the current time.\n\
4204Specifying tuples for both times and ns is an error.\n\
4205\n\
4206If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4207 and path should be relative; path will then be relative to that directory.\n\
4208If follow_symlinks is False, and the last element of the path is a symbolic\n\
4209 link, utime will modify the symbolic link itself instead of the file the\n\
4210 link points to.\n\
4211It is an error to use dir_fd or follow_symlinks when specifying path\n\
4212 as an open file descriptor.\n\
4213dir_fd and follow_symlinks may not be available on your platform.\n\
4214 If they are unavailable, using them will raise a NotImplementedError.");
4215
4216typedef struct {
4217 int now;
4218 time_t atime_s;
4219 long atime_ns;
4220 time_t mtime_s;
4221 long mtime_ns;
4222} utime_t;
4223
4224/*
4225 * these macros assume that "utime" is a pointer to a utime_t
4226 * they also intentionally leak the declaration of a pointer named "time"
4227 */
4228#define UTIME_TO_TIMESPEC \
4229 struct timespec ts[2]; \
4230 struct timespec *time; \
4231 if (utime->now) \
4232 time = NULL; \
4233 else { \
4234 ts[0].tv_sec = utime->atime_s; \
4235 ts[0].tv_nsec = utime->atime_ns; \
4236 ts[1].tv_sec = utime->mtime_s; \
4237 ts[1].tv_nsec = utime->mtime_ns; \
4238 time = ts; \
4239 } \
4240
4241#define UTIME_TO_TIMEVAL \
4242 struct timeval tv[2]; \
4243 struct timeval *time; \
4244 if (utime->now) \
4245 time = NULL; \
4246 else { \
4247 tv[0].tv_sec = utime->atime_s; \
4248 tv[0].tv_usec = utime->atime_ns / 1000; \
4249 tv[1].tv_sec = utime->mtime_s; \
4250 tv[1].tv_usec = utime->mtime_ns / 1000; \
4251 time = tv; \
4252 } \
4253
4254#define UTIME_TO_UTIMBUF \
4255 struct utimbuf u[2]; \
4256 struct utimbuf *time; \
4257 if (utime->now) \
4258 time = NULL; \
4259 else { \
4260 u.actime = utime->atime_s; \
4261 u.modtime = utime->mtime_s; \
4262 time = u; \
4263 }
4264
4265#define UTIME_TO_TIME_T \
4266 time_t timet[2]; \
4267 struct timet time; \
4268 if (utime->now) \
4269 time = NULL; \
4270 else { \
4271 timet[0] = utime->atime_s; \
4272 timet[1] = utime->mtime_s; \
4273 time = &timet; \
4274 } \
4275
4276
4277#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4278
4279#if UTIME_HAVE_DIR_FD
4280
4281static int
4282utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4283{
4284#ifdef HAVE_UTIMENSAT
4285 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4286 UTIME_TO_TIMESPEC;
4287 return utimensat(dir_fd, path, time, flags);
4288#elif defined(HAVE_FUTIMESAT)
4289 UTIME_TO_TIMEVAL;
4290 /*
4291 * follow_symlinks will never be false here;
4292 * we only allow !follow_symlinks and dir_fd together
4293 * if we have utimensat()
4294 */
4295 assert(follow_symlinks);
4296 return futimesat(dir_fd, path, time);
4297#endif
4298}
4299
4300#endif
4301
4302#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4303
4304#if UTIME_HAVE_FD
4305
4306static int
4307utime_fd(utime_t *utime, int fd)
4308{
4309#ifdef HAVE_FUTIMENS
4310 UTIME_TO_TIMESPEC;
4311 return futimens(fd, time);
4312#else
4313 UTIME_TO_TIMEVAL;
4314 return futimes(fd, time);
4315#endif
4316}
4317
4318#endif
4319
4320
4321#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4322 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4323
4324#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4325
4326static int
4327utime_nofollow_symlinks(utime_t *utime, char *path)
4328{
4329#ifdef HAVE_UTIMENSAT
4330 UTIME_TO_TIMESPEC;
4331 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4332#else
4333 UTIME_TO_TIMEVAL;
4334 return lutimes(path, time);
4335#endif
4336}
4337
4338#endif
4339
4340#ifndef MS_WINDOWS
4341
4342static int
4343utime_default(utime_t *utime, char *path)
4344{
4345#ifdef HAVE_UTIMENSAT
4346 UTIME_TO_TIMESPEC;
4347 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4348#elif defined(HAVE_UTIMES)
4349 UTIME_TO_TIMEVAL;
4350 return utimes(path, time);
4351#elif defined(HAVE_UTIME_H)
4352 UTIME_TO_UTIMBUF;
4353 return utime(path, time);
4354#else
4355 UTIME_TO_TIME_T;
4356 return utime(path, time);
4357#endif
4358}
4359
4360#endif
4361
Larry Hastings76ad59b2012-05-03 00:30:07 -07004362static int
4363split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4364{
4365 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004366 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004367 divmod = PyNumber_Divmod(py_long, billion);
4368 if (!divmod)
4369 goto exit;
4370 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4371 if ((*s == -1) && PyErr_Occurred())
4372 goto exit;
4373 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004374 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004375 goto exit;
4376
4377 result = 1;
4378exit:
4379 Py_XDECREF(divmod);
4380 return result;
4381}
4382
Larry Hastings9cf065c2012-06-22 16:30:09 -07004383static PyObject *
4384posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004385{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004386 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004387 PyObject *times = NULL;
4388 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004389 int dir_fd = DEFAULT_DIR_FD;
4390 int follow_symlinks = 1;
4391 char *keywords[] = {"path", "times", "ns", "dir_fd",
4392 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004393
Larry Hastings9cf065c2012-06-22 16:30:09 -07004394 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004395
Larry Hastings9cf065c2012-06-22 16:30:09 -07004396#ifdef MS_WINDOWS
4397 HANDLE hFile;
4398 FILETIME atime, mtime;
4399#else
4400 int result;
4401#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004402
Larry Hastings9cf065c2012-06-22 16:30:09 -07004403 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004404
Larry Hastings9cf065c2012-06-22 16:30:09 -07004405 memset(&path, 0, sizeof(path));
4406#if UTIME_HAVE_FD
4407 path.allow_fd = 1;
4408#endif
4409 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4410 "O&|O$OO&p:utime", keywords,
4411 path_converter, &path,
4412 &times, &ns,
4413#if UTIME_HAVE_DIR_FD
4414 dir_fd_converter, &dir_fd,
4415#else
4416 dir_fd_unavailable, &dir_fd,
4417#endif
4418 &follow_symlinks
4419 ))
4420 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004421
Larry Hastings9cf065c2012-06-22 16:30:09 -07004422 if (times && (times != Py_None) && ns) {
4423 PyErr_SetString(PyExc_ValueError,
4424 "utime: you may specify either 'times'"
4425 " or 'ns' but not both");
4426 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004427 }
4428
4429 if (times && (times != Py_None)) {
4430 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004431 PyErr_SetString(PyExc_TypeError,
4432 "utime: 'times' must be either"
4433 " a tuple of two ints or None");
4434 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004435 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004436 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004437 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004438 &utime.atime_s, &utime.atime_ns) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004439 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004440 &utime.mtime_s, &utime.mtime_ns) == -1) {
4441 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004442 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004443 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004444 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004445 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004446 PyErr_SetString(PyExc_TypeError,
4447 "utime: 'ns' must be a tuple of two ints");
4448 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004449 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004450 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004451 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004452 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004453 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004454 &utime.mtime_s, &utime.mtime_ns)) {
4455 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004456 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004457 }
4458 else {
4459 /* times and ns are both None/unspecified. use "now". */
4460 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004461 }
4462
Larry Hastings9cf065c2012-06-22 16:30:09 -07004463#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4464 if (follow_symlinks_specified("utime", follow_symlinks))
4465 goto exit;
4466#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004467
Larry Hastings9cf065c2012-06-22 16:30:09 -07004468 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4469 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4470 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4471 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004472
Larry Hastings9cf065c2012-06-22 16:30:09 -07004473#if !defined(HAVE_UTIMENSAT)
4474 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004475 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004476 "utime: cannot use dir_fd and follow_symlinks "
4477 "together on this platform");
4478 goto exit;
4479 }
4480#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004481
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004482#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004483 Py_BEGIN_ALLOW_THREADS
4484 if (path.wide)
4485 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004486 NULL, OPEN_EXISTING,
4487 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004488 else
4489 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004490 NULL, OPEN_EXISTING,
4491 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004492 Py_END_ALLOW_THREADS
4493 if (hFile == INVALID_HANDLE_VALUE) {
4494 win32_error_object("utime", path.object);
4495 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004496 }
4497
Larry Hastings9cf065c2012-06-22 16:30:09 -07004498 if (utime.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004499 SYSTEMTIME now;
4500 GetSystemTime(&now);
4501 if (!SystemTimeToFileTime(&now, &mtime) ||
4502 !SystemTimeToFileTime(&now, &atime)) {
4503 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004504 goto exit;
Stefan Krah0e803b32010-11-26 16:16:47 +00004505 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004506 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004507 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004508 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4509 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004510 }
4511 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4512 /* Avoid putting the file name into the error here,
4513 as that may confuse the user into believing that
4514 something is wrong with the file, when it also
4515 could be the time stamp that gives a problem. */
4516 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004517 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004518 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004519#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004520 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004521
Larry Hastings9cf065c2012-06-22 16:30:09 -07004522#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4523 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4524 result = utime_nofollow_symlinks(&utime, path.narrow);
4525 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004526#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004527
4528#if UTIME_HAVE_DIR_FD
4529 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4530 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4531 else
4532#endif
4533
4534#if UTIME_HAVE_FD
4535 if (path.fd != -1)
4536 result = utime_fd(&utime, path.fd);
4537 else
4538#endif
4539
4540 result = utime_default(&utime, path.narrow);
4541
4542 Py_END_ALLOW_THREADS
4543
4544 if (result < 0) {
4545 /* see previous comment about not putting filename in error here */
4546 return_value = posix_error();
4547 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004548 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004549
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004550#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004551
4552 Py_INCREF(Py_None);
4553 return_value = Py_None;
4554
4555exit:
4556 path_cleanup(&path);
4557#ifdef MS_WINDOWS
4558 if (hFile != INVALID_HANDLE_VALUE)
4559 CloseHandle(hFile);
4560#endif
4561 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004562}
4563
Guido van Rossum3b066191991-06-04 19:40:25 +00004564/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004565
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004566PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004567"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004568Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004569
Barry Warsaw53699e91996-12-10 23:23:01 +00004570static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004571posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004572{
Victor Stinner8c62be82010-05-06 00:08:46 +00004573 int sts;
4574 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
4575 return NULL;
4576 _exit(sts);
4577 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004578}
4579
Martin v. Löwis114619e2002-10-07 06:44:21 +00004580#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4581static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004582free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004583{
Victor Stinner8c62be82010-05-06 00:08:46 +00004584 Py_ssize_t i;
4585 for (i = 0; i < count; i++)
4586 PyMem_Free(array[i]);
4587 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004588}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004589
Antoine Pitrou69f71142009-05-24 21:25:49 +00004590static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004591int fsconvert_strdup(PyObject *o, char**out)
4592{
Victor Stinner8c62be82010-05-06 00:08:46 +00004593 PyObject *bytes;
4594 Py_ssize_t size;
4595 if (!PyUnicode_FSConverter(o, &bytes))
4596 return 0;
4597 size = PyBytes_GET_SIZE(bytes);
4598 *out = PyMem_Malloc(size+1);
4599 if (!*out)
4600 return 0;
4601 memcpy(*out, PyBytes_AsString(bytes), size+1);
4602 Py_DECREF(bytes);
4603 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004604}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004605#endif
4606
Ross Lagerwall7807c352011-03-17 20:20:30 +02004607#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004608static char**
4609parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4610{
Victor Stinner8c62be82010-05-06 00:08:46 +00004611 char **envlist;
4612 Py_ssize_t i, pos, envc;
4613 PyObject *keys=NULL, *vals=NULL;
4614 PyObject *key, *val, *key2, *val2;
4615 char *p, *k, *v;
4616 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004617
Victor Stinner8c62be82010-05-06 00:08:46 +00004618 i = PyMapping_Size(env);
4619 if (i < 0)
4620 return NULL;
4621 envlist = PyMem_NEW(char *, i + 1);
4622 if (envlist == NULL) {
4623 PyErr_NoMemory();
4624 return NULL;
4625 }
4626 envc = 0;
4627 keys = PyMapping_Keys(env);
4628 vals = PyMapping_Values(env);
4629 if (!keys || !vals)
4630 goto error;
4631 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4632 PyErr_Format(PyExc_TypeError,
4633 "env.keys() or env.values() is not a list");
4634 goto error;
4635 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004636
Victor Stinner8c62be82010-05-06 00:08:46 +00004637 for (pos = 0; pos < i; pos++) {
4638 key = PyList_GetItem(keys, pos);
4639 val = PyList_GetItem(vals, pos);
4640 if (!key || !val)
4641 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004642
Victor Stinner8c62be82010-05-06 00:08:46 +00004643 if (PyUnicode_FSConverter(key, &key2) == 0)
4644 goto error;
4645 if (PyUnicode_FSConverter(val, &val2) == 0) {
4646 Py_DECREF(key2);
4647 goto error;
4648 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004649
Victor Stinner8c62be82010-05-06 00:08:46 +00004650 k = PyBytes_AsString(key2);
4651 v = PyBytes_AsString(val2);
4652 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004653
Victor Stinner8c62be82010-05-06 00:08:46 +00004654 p = PyMem_NEW(char, len);
4655 if (p == NULL) {
4656 PyErr_NoMemory();
4657 Py_DECREF(key2);
4658 Py_DECREF(val2);
4659 goto error;
4660 }
4661 PyOS_snprintf(p, len, "%s=%s", k, v);
4662 envlist[envc++] = p;
4663 Py_DECREF(key2);
4664 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00004665 }
4666 Py_DECREF(vals);
4667 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004668
Victor Stinner8c62be82010-05-06 00:08:46 +00004669 envlist[envc] = 0;
4670 *envc_ptr = envc;
4671 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004672
4673error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004674 Py_XDECREF(keys);
4675 Py_XDECREF(vals);
4676 while (--envc >= 0)
4677 PyMem_DEL(envlist[envc]);
4678 PyMem_DEL(envlist);
4679 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004680}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004681
Ross Lagerwall7807c352011-03-17 20:20:30 +02004682static char**
4683parse_arglist(PyObject* argv, Py_ssize_t *argc)
4684{
4685 int i;
4686 char **argvlist = PyMem_NEW(char *, *argc+1);
4687 if (argvlist == NULL) {
4688 PyErr_NoMemory();
4689 return NULL;
4690 }
4691 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004692 PyObject* item = PySequence_ITEM(argv, i);
4693 if (item == NULL)
4694 goto fail;
4695 if (!fsconvert_strdup(item, &argvlist[i])) {
4696 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004697 goto fail;
4698 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004699 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004700 }
4701 argvlist[*argc] = NULL;
4702 return argvlist;
4703fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004704 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004705 free_string_array(argvlist, *argc);
4706 return NULL;
4707}
4708#endif
4709
4710#ifdef HAVE_EXECV
4711PyDoc_STRVAR(posix_execv__doc__,
4712"execv(path, args)\n\n\
4713Execute an executable path with arguments, replacing current process.\n\
4714\n\
4715 path: path of executable file\n\
4716 args: tuple or list of strings");
4717
4718static PyObject *
4719posix_execv(PyObject *self, PyObject *args)
4720{
4721 PyObject *opath;
4722 char *path;
4723 PyObject *argv;
4724 char **argvlist;
4725 Py_ssize_t argc;
4726
4727 /* execv has two arguments: (path, argv), where
4728 argv is a list or tuple of strings. */
4729
4730 if (!PyArg_ParseTuple(args, "O&O:execv",
4731 PyUnicode_FSConverter,
4732 &opath, &argv))
4733 return NULL;
4734 path = PyBytes_AsString(opath);
4735 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4736 PyErr_SetString(PyExc_TypeError,
4737 "execv() arg 2 must be a tuple or list");
4738 Py_DECREF(opath);
4739 return NULL;
4740 }
4741 argc = PySequence_Size(argv);
4742 if (argc < 1) {
4743 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
4744 Py_DECREF(opath);
4745 return NULL;
4746 }
4747
4748 argvlist = parse_arglist(argv, &argc);
4749 if (argvlist == NULL) {
4750 Py_DECREF(opath);
4751 return NULL;
4752 }
4753
4754 execv(path, argvlist);
4755
4756 /* If we get here it's definitely an error */
4757
4758 free_string_array(argvlist, argc);
4759 Py_DECREF(opath);
4760 return posix_error();
4761}
4762
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004763PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004764"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004765Execute a path with arguments and environment, replacing current process.\n\
4766\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004767 path: path of executable file\n\
4768 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004769 env: dictionary of strings mapping to strings\n\
4770\n\
4771On some platforms, you may specify an open file descriptor for path;\n\
4772 execve will execute the program the file descriptor is open to.\n\
4773 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004774
Barry Warsaw53699e91996-12-10 23:23:01 +00004775static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004776posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004777{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004778 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004779 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004780 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004781 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004782 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004783 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004784
Victor Stinner8c62be82010-05-06 00:08:46 +00004785 /* execve has three arguments: (path, argv, env), where
4786 argv is a list or tuple of strings and env is a dictionary
4787 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004788
Larry Hastings9cf065c2012-06-22 16:30:09 -07004789 memset(&path, 0, sizeof(path));
4790#ifdef HAVE_FEXECVE
4791 path.allow_fd = 1;
4792#endif
4793 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
4794 path_converter, &path,
4795 &argv, &env
4796 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00004797 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004798
Ross Lagerwall7807c352011-03-17 20:20:30 +02004799 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004800 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004801 "execve: argv must be a tuple or list");
4802 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004803 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004804 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00004805 if (!PyMapping_Check(env)) {
4806 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004807 "execve: environment must be a mapping object");
4808 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004809 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004810
Ross Lagerwall7807c352011-03-17 20:20:30 +02004811 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004812 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004813 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004814 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004815
Victor Stinner8c62be82010-05-06 00:08:46 +00004816 envlist = parse_envlist(env, &envc);
4817 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02004818 goto fail;
4819
Larry Hastings9cf065c2012-06-22 16:30:09 -07004820#ifdef HAVE_FEXECVE
4821 if (path.fd > -1)
4822 fexecve(path.fd, argvlist, envlist);
4823 else
4824#endif
4825 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004826
4827 /* If we get here it's definitely an error */
4828
Larry Hastings9cf065c2012-06-22 16:30:09 -07004829 path_posix_error("execve", &path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004830
4831 while (--envc >= 0)
4832 PyMem_DEL(envlist[envc]);
4833 PyMem_DEL(envlist);
4834 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004835 if (argvlist)
4836 free_string_array(argvlist, argc);
4837 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004838 return NULL;
4839}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004840#endif /* HAVE_EXECV */
4841
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004842
Guido van Rossuma1065681999-01-25 23:20:23 +00004843#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004844PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004845"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004846Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004847\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004848 mode: mode of process creation\n\
4849 path: path of executable file\n\
4850 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004851
4852static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004853posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004854{
Victor Stinner8c62be82010-05-06 00:08:46 +00004855 PyObject *opath;
4856 char *path;
4857 PyObject *argv;
4858 char **argvlist;
4859 int mode, i;
4860 Py_ssize_t argc;
4861 Py_intptr_t spawnval;
4862 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00004863
Victor Stinner8c62be82010-05-06 00:08:46 +00004864 /* spawnv has three arguments: (mode, path, argv), where
4865 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004866
Victor Stinner8c62be82010-05-06 00:08:46 +00004867 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
4868 PyUnicode_FSConverter,
4869 &opath, &argv))
4870 return NULL;
4871 path = PyBytes_AsString(opath);
4872 if (PyList_Check(argv)) {
4873 argc = PyList_Size(argv);
4874 getitem = PyList_GetItem;
4875 }
4876 else if (PyTuple_Check(argv)) {
4877 argc = PyTuple_Size(argv);
4878 getitem = PyTuple_GetItem;
4879 }
4880 else {
4881 PyErr_SetString(PyExc_TypeError,
4882 "spawnv() arg 2 must be a tuple or list");
4883 Py_DECREF(opath);
4884 return NULL;
4885 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004886
Victor Stinner8c62be82010-05-06 00:08:46 +00004887 argvlist = PyMem_NEW(char *, argc+1);
4888 if (argvlist == NULL) {
4889 Py_DECREF(opath);
4890 return PyErr_NoMemory();
4891 }
4892 for (i = 0; i < argc; i++) {
4893 if (!fsconvert_strdup((*getitem)(argv, i),
4894 &argvlist[i])) {
4895 free_string_array(argvlist, i);
4896 PyErr_SetString(
4897 PyExc_TypeError,
4898 "spawnv() arg 2 must contain only strings");
4899 Py_DECREF(opath);
4900 return NULL;
4901 }
4902 }
4903 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004904
Victor Stinner8c62be82010-05-06 00:08:46 +00004905 if (mode == _OLD_P_OVERLAY)
4906 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00004907
Victor Stinner8c62be82010-05-06 00:08:46 +00004908 Py_BEGIN_ALLOW_THREADS
4909 spawnval = _spawnv(mode, path, argvlist);
4910 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00004911
Victor Stinner8c62be82010-05-06 00:08:46 +00004912 free_string_array(argvlist, argc);
4913 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00004914
Victor Stinner8c62be82010-05-06 00:08:46 +00004915 if (spawnval == -1)
4916 return posix_error();
4917 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004918#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00004919 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004920#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004921 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004922#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00004923}
4924
4925
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004926PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004927"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004928Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004929\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004930 mode: mode of process creation\n\
4931 path: path of executable file\n\
4932 args: tuple or list of arguments\n\
4933 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004934
4935static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004936posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004937{
Victor Stinner8c62be82010-05-06 00:08:46 +00004938 PyObject *opath;
4939 char *path;
4940 PyObject *argv, *env;
4941 char **argvlist;
4942 char **envlist;
4943 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00004944 int mode;
4945 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00004946 Py_intptr_t spawnval;
4947 PyObject *(*getitem)(PyObject *, Py_ssize_t);
4948 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00004949
Victor Stinner8c62be82010-05-06 00:08:46 +00004950 /* spawnve has four arguments: (mode, path, argv, env), where
4951 argv is a list or tuple of strings and env is a dictionary
4952 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004953
Victor Stinner8c62be82010-05-06 00:08:46 +00004954 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
4955 PyUnicode_FSConverter,
4956 &opath, &argv, &env))
4957 return NULL;
4958 path = PyBytes_AsString(opath);
4959 if (PyList_Check(argv)) {
4960 argc = PyList_Size(argv);
4961 getitem = PyList_GetItem;
4962 }
4963 else if (PyTuple_Check(argv)) {
4964 argc = PyTuple_Size(argv);
4965 getitem = PyTuple_GetItem;
4966 }
4967 else {
4968 PyErr_SetString(PyExc_TypeError,
4969 "spawnve() arg 2 must be a tuple or list");
4970 goto fail_0;
4971 }
4972 if (!PyMapping_Check(env)) {
4973 PyErr_SetString(PyExc_TypeError,
4974 "spawnve() arg 3 must be a mapping object");
4975 goto fail_0;
4976 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004977
Victor Stinner8c62be82010-05-06 00:08:46 +00004978 argvlist = PyMem_NEW(char *, argc+1);
4979 if (argvlist == NULL) {
4980 PyErr_NoMemory();
4981 goto fail_0;
4982 }
4983 for (i = 0; i < argc; i++) {
4984 if (!fsconvert_strdup((*getitem)(argv, i),
4985 &argvlist[i]))
4986 {
4987 lastarg = i;
4988 goto fail_1;
4989 }
4990 }
4991 lastarg = argc;
4992 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004993
Victor Stinner8c62be82010-05-06 00:08:46 +00004994 envlist = parse_envlist(env, &envc);
4995 if (envlist == NULL)
4996 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00004997
Victor Stinner8c62be82010-05-06 00:08:46 +00004998 if (mode == _OLD_P_OVERLAY)
4999 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005000
Victor Stinner8c62be82010-05-06 00:08:46 +00005001 Py_BEGIN_ALLOW_THREADS
5002 spawnval = _spawnve(mode, path, argvlist, envlist);
5003 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005004
Victor Stinner8c62be82010-05-06 00:08:46 +00005005 if (spawnval == -1)
5006 (void) posix_error();
5007 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005008#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005009 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005010#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005011 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005012#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005013
Victor Stinner8c62be82010-05-06 00:08:46 +00005014 while (--envc >= 0)
5015 PyMem_DEL(envlist[envc]);
5016 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005017 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005018 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005019 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005020 Py_DECREF(opath);
5021 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005022}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005023
Guido van Rossuma1065681999-01-25 23:20:23 +00005024#endif /* HAVE_SPAWNV */
5025
5026
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005027#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005028PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005029"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005030Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5031\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005032Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005033
5034static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005035posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005036{
Victor Stinner8c62be82010-05-06 00:08:46 +00005037 pid_t pid;
5038 int result = 0;
5039 _PyImport_AcquireLock();
5040 pid = fork1();
5041 if (pid == 0) {
5042 /* child: this clobbers and resets the import lock. */
5043 PyOS_AfterFork();
5044 } else {
5045 /* parent: release the import lock. */
5046 result = _PyImport_ReleaseLock();
5047 }
5048 if (pid == -1)
5049 return posix_error();
5050 if (result < 0) {
5051 /* Don't clobber the OSError if the fork failed. */
5052 PyErr_SetString(PyExc_RuntimeError,
5053 "not holding the import lock");
5054 return NULL;
5055 }
5056 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005057}
5058#endif
5059
5060
Guido van Rossumad0ee831995-03-01 10:34:45 +00005061#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005062PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005063"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005064Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005065Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005066
Barry Warsaw53699e91996-12-10 23:23:01 +00005067static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005068posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005069{
Victor Stinner8c62be82010-05-06 00:08:46 +00005070 pid_t pid;
5071 int result = 0;
5072 _PyImport_AcquireLock();
5073 pid = fork();
5074 if (pid == 0) {
5075 /* child: this clobbers and resets the import lock. */
5076 PyOS_AfterFork();
5077 } else {
5078 /* parent: release the import lock. */
5079 result = _PyImport_ReleaseLock();
5080 }
5081 if (pid == -1)
5082 return posix_error();
5083 if (result < 0) {
5084 /* Don't clobber the OSError if the fork failed. */
5085 PyErr_SetString(PyExc_RuntimeError,
5086 "not holding the import lock");
5087 return NULL;
5088 }
5089 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005090}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005091#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005092
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005093#ifdef HAVE_SCHED_H
5094
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005095#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5096
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005097PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5098"sched_get_priority_max(policy)\n\n\
5099Get the maximum scheduling priority for *policy*.");
5100
5101static PyObject *
5102posix_sched_get_priority_max(PyObject *self, PyObject *args)
5103{
5104 int policy, max;
5105
5106 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5107 return NULL;
5108 max = sched_get_priority_max(policy);
5109 if (max < 0)
5110 return posix_error();
5111 return PyLong_FromLong(max);
5112}
5113
5114PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5115"sched_get_priority_min(policy)\n\n\
5116Get the minimum scheduling priority for *policy*.");
5117
5118static PyObject *
5119posix_sched_get_priority_min(PyObject *self, PyObject *args)
5120{
5121 int policy, min;
5122
5123 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5124 return NULL;
5125 min = sched_get_priority_min(policy);
5126 if (min < 0)
5127 return posix_error();
5128 return PyLong_FromLong(min);
5129}
5130
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005131#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5132
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005133#ifdef HAVE_SCHED_SETSCHEDULER
5134
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005135PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5136"sched_getscheduler(pid)\n\n\
5137Get the scheduling policy for the process with a PID of *pid*.\n\
5138Passing a PID of 0 returns the scheduling policy for the calling process.");
5139
5140static PyObject *
5141posix_sched_getscheduler(PyObject *self, PyObject *args)
5142{
5143 pid_t pid;
5144 int policy;
5145
5146 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5147 return NULL;
5148 policy = sched_getscheduler(pid);
5149 if (policy < 0)
5150 return posix_error();
5151 return PyLong_FromLong(policy);
5152}
5153
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005154#endif
5155
5156#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5157
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005158static PyObject *
5159sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5160{
5161 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005162 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005163
5164 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5165 return NULL;
5166 res = PyStructSequence_New(type);
5167 if (!res)
5168 return NULL;
5169 Py_INCREF(priority);
5170 PyStructSequence_SET_ITEM(res, 0, priority);
5171 return res;
5172}
5173
5174PyDoc_STRVAR(sched_param__doc__,
5175"sched_param(sched_priority): A scheduling parameter.\n\n\
5176Current has only one field: sched_priority");
5177
5178static PyStructSequence_Field sched_param_fields[] = {
5179 {"sched_priority", "the scheduling priority"},
5180 {0}
5181};
5182
5183static PyStructSequence_Desc sched_param_desc = {
5184 "sched_param", /* name */
5185 sched_param__doc__, /* doc */
5186 sched_param_fields,
5187 1
5188};
5189
5190static int
5191convert_sched_param(PyObject *param, struct sched_param *res)
5192{
5193 long priority;
5194
5195 if (Py_TYPE(param) != &SchedParamType) {
5196 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5197 return 0;
5198 }
5199 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5200 if (priority == -1 && PyErr_Occurred())
5201 return 0;
5202 if (priority > INT_MAX || priority < INT_MIN) {
5203 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5204 return 0;
5205 }
5206 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5207 return 1;
5208}
5209
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005210#endif
5211
5212#ifdef HAVE_SCHED_SETSCHEDULER
5213
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005214PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5215"sched_setscheduler(pid, policy, param)\n\n\
5216Set the scheduling policy, *policy*, for *pid*.\n\
5217If *pid* is 0, the calling process is changed.\n\
5218*param* is an instance of sched_param.");
5219
5220static PyObject *
5221posix_sched_setscheduler(PyObject *self, PyObject *args)
5222{
5223 pid_t pid;
5224 int policy;
5225 struct sched_param param;
5226
5227 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5228 &pid, &policy, &convert_sched_param, &param))
5229 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005230
5231 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005232 ** sched_setscheduler() returns 0 in Linux, but the previous
5233 ** scheduling policy under Solaris/Illumos, and others.
5234 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005235 */
5236 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005237 return posix_error();
5238 Py_RETURN_NONE;
5239}
5240
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005241#endif
5242
5243#ifdef HAVE_SCHED_SETPARAM
5244
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005245PyDoc_STRVAR(posix_sched_getparam__doc__,
5246"sched_getparam(pid) -> sched_param\n\n\
5247Returns scheduling parameters for the process with *pid* as an instance of the\n\
5248sched_param class. A PID of 0 means the calling process.");
5249
5250static PyObject *
5251posix_sched_getparam(PyObject *self, PyObject *args)
5252{
5253 pid_t pid;
5254 struct sched_param param;
5255 PyObject *res, *priority;
5256
5257 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5258 return NULL;
5259 if (sched_getparam(pid, &param))
5260 return posix_error();
5261 res = PyStructSequence_New(&SchedParamType);
5262 if (!res)
5263 return NULL;
5264 priority = PyLong_FromLong(param.sched_priority);
5265 if (!priority) {
5266 Py_DECREF(res);
5267 return NULL;
5268 }
5269 PyStructSequence_SET_ITEM(res, 0, priority);
5270 return res;
5271}
5272
5273PyDoc_STRVAR(posix_sched_setparam__doc__,
5274"sched_setparam(pid, param)\n\n\
5275Set scheduling parameters for a process with PID *pid*.\n\
5276A PID of 0 means the calling process.");
5277
5278static PyObject *
5279posix_sched_setparam(PyObject *self, PyObject *args)
5280{
5281 pid_t pid;
5282 struct sched_param param;
5283
5284 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5285 &pid, &convert_sched_param, &param))
5286 return NULL;
5287 if (sched_setparam(pid, &param))
5288 return posix_error();
5289 Py_RETURN_NONE;
5290}
5291
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005292#endif
5293
5294#ifdef HAVE_SCHED_RR_GET_INTERVAL
5295
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005296PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5297"sched_rr_get_interval(pid) -> float\n\n\
5298Return the round-robin quantum for the process with PID *pid* in seconds.");
5299
5300static PyObject *
5301posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5302{
5303 pid_t pid;
5304 struct timespec interval;
5305
5306 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5307 return NULL;
5308 if (sched_rr_get_interval(pid, &interval))
5309 return posix_error();
5310 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5311}
5312
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005313#endif
5314
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005315PyDoc_STRVAR(posix_sched_yield__doc__,
5316"sched_yield()\n\n\
5317Voluntarily relinquish the CPU.");
5318
5319static PyObject *
5320posix_sched_yield(PyObject *self, PyObject *noargs)
5321{
5322 if (sched_yield())
5323 return posix_error();
5324 Py_RETURN_NONE;
5325}
5326
Benjamin Peterson2740af82011-08-02 17:41:34 -05005327#ifdef HAVE_SCHED_SETAFFINITY
5328
Antoine Pitrou84869872012-08-04 16:16:35 +02005329/* The minimum number of CPUs allocated in a cpu_set_t */
5330static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005331
5332PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5333"sched_setaffinity(pid, cpu_set)\n\n\
5334Set the affinity of the process with PID *pid* to *cpu_set*.");
5335
5336static PyObject *
5337posix_sched_setaffinity(PyObject *self, PyObject *args)
5338{
5339 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005340 int ncpus;
5341 size_t setsize;
5342 cpu_set_t *mask = NULL;
5343 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005344
Antoine Pitrou84869872012-08-04 16:16:35 +02005345 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5346 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005347 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005348
5349 iterator = PyObject_GetIter(iterable);
5350 if (iterator == NULL)
5351 return NULL;
5352
5353 ncpus = NCPUS_START;
5354 setsize = CPU_ALLOC_SIZE(ncpus);
5355 mask = CPU_ALLOC(ncpus);
5356 if (mask == NULL) {
5357 PyErr_NoMemory();
5358 goto error;
5359 }
5360 CPU_ZERO_S(setsize, mask);
5361
5362 while ((item = PyIter_Next(iterator))) {
5363 long cpu;
5364 if (!PyLong_Check(item)) {
5365 PyErr_Format(PyExc_TypeError,
5366 "expected an iterator of ints, "
5367 "but iterator yielded %R",
5368 Py_TYPE(item));
5369 Py_DECREF(item);
5370 goto error;
5371 }
5372 cpu = PyLong_AsLong(item);
5373 Py_DECREF(item);
5374 if (cpu < 0) {
5375 if (!PyErr_Occurred())
5376 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5377 goto error;
5378 }
5379 if (cpu > INT_MAX - 1) {
5380 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5381 goto error;
5382 }
5383 if (cpu >= ncpus) {
5384 /* Grow CPU mask to fit the CPU number */
5385 int newncpus = ncpus;
5386 cpu_set_t *newmask;
5387 size_t newsetsize;
5388 while (newncpus <= cpu) {
5389 if (newncpus > INT_MAX / 2)
5390 newncpus = cpu + 1;
5391 else
5392 newncpus = newncpus * 2;
5393 }
5394 newmask = CPU_ALLOC(newncpus);
5395 if (newmask == NULL) {
5396 PyErr_NoMemory();
5397 goto error;
5398 }
5399 newsetsize = CPU_ALLOC_SIZE(newncpus);
5400 CPU_ZERO_S(newsetsize, newmask);
5401 memcpy(newmask, mask, setsize);
5402 CPU_FREE(mask);
5403 setsize = newsetsize;
5404 mask = newmask;
5405 ncpus = newncpus;
5406 }
5407 CPU_SET_S(cpu, setsize, mask);
5408 }
5409 Py_CLEAR(iterator);
5410
5411 if (sched_setaffinity(pid, setsize, mask)) {
5412 posix_error();
5413 goto error;
5414 }
5415 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005416 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005417
5418error:
5419 if (mask)
5420 CPU_FREE(mask);
5421 Py_XDECREF(iterator);
5422 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005423}
5424
5425PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5426"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5427Return the affinity of the process with PID *pid*.\n\
5428The returned cpu_set will be of size *ncpus*.");
5429
5430static PyObject *
5431posix_sched_getaffinity(PyObject *self, PyObject *args)
5432{
5433 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005434 int cpu, ncpus, count;
5435 size_t setsize;
5436 cpu_set_t *mask = NULL;
5437 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005438
Antoine Pitrou84869872012-08-04 16:16:35 +02005439 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
5440 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005441 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005442
5443 ncpus = NCPUS_START;
5444 while (1) {
5445 setsize = CPU_ALLOC_SIZE(ncpus);
5446 mask = CPU_ALLOC(ncpus);
5447 if (mask == NULL)
5448 return PyErr_NoMemory();
5449 if (sched_getaffinity(pid, setsize, mask) == 0)
5450 break;
5451 CPU_FREE(mask);
5452 if (errno != EINVAL)
5453 return posix_error();
5454 if (ncpus > INT_MAX / 2) {
5455 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5456 "a large enough CPU set");
5457 return NULL;
5458 }
5459 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005460 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005461
5462 res = PySet_New(NULL);
5463 if (res == NULL)
5464 goto error;
5465 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5466 if (CPU_ISSET_S(cpu, setsize, mask)) {
5467 PyObject *cpu_num = PyLong_FromLong(cpu);
5468 --count;
5469 if (cpu_num == NULL)
5470 goto error;
5471 if (PySet_Add(res, cpu_num)) {
5472 Py_DECREF(cpu_num);
5473 goto error;
5474 }
5475 Py_DECREF(cpu_num);
5476 }
5477 }
5478 CPU_FREE(mask);
5479 return res;
5480
5481error:
5482 if (mask)
5483 CPU_FREE(mask);
5484 Py_XDECREF(res);
5485 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005486}
5487
Benjamin Peterson2740af82011-08-02 17:41:34 -05005488#endif /* HAVE_SCHED_SETAFFINITY */
5489
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005490#endif /* HAVE_SCHED_H */
5491
Neal Norwitzb59798b2003-03-21 01:43:31 +00005492/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005493/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5494#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005495#define DEV_PTY_FILE "/dev/ptc"
5496#define HAVE_DEV_PTMX
5497#else
5498#define DEV_PTY_FILE "/dev/ptmx"
5499#endif
5500
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005501#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005502#ifdef HAVE_PTY_H
5503#include <pty.h>
5504#else
5505#ifdef HAVE_LIBUTIL_H
5506#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005507#else
5508#ifdef HAVE_UTIL_H
5509#include <util.h>
5510#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005511#endif /* HAVE_LIBUTIL_H */
5512#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005513#ifdef HAVE_STROPTS_H
5514#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005515#endif
5516#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005517
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005518#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005519PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005520"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005521Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005522
5523static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005524posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005525{
Victor Stinner8c62be82010-05-06 00:08:46 +00005526 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005527#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005528 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005529#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005530#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005531 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005532#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005533 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005534#endif
5535#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005536
Thomas Wouters70c21a12000-07-14 14:28:33 +00005537#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005538 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
5539 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005540#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005541 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5542 if (slave_name == NULL)
5543 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00005544
Victor Stinner8c62be82010-05-06 00:08:46 +00005545 slave_fd = open(slave_name, O_RDWR);
5546 if (slave_fd < 0)
5547 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005548#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005549 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
5550 if (master_fd < 0)
5551 return posix_error();
5552 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
5553 /* change permission of slave */
5554 if (grantpt(master_fd) < 0) {
5555 PyOS_setsig(SIGCHLD, sig_saved);
5556 return posix_error();
5557 }
5558 /* unlock slave */
5559 if (unlockpt(master_fd) < 0) {
5560 PyOS_setsig(SIGCHLD, sig_saved);
5561 return posix_error();
5562 }
5563 PyOS_setsig(SIGCHLD, sig_saved);
5564 slave_name = ptsname(master_fd); /* get name of slave */
5565 if (slave_name == NULL)
5566 return posix_error();
5567 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
5568 if (slave_fd < 0)
5569 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005570#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005571 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5572 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005573#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005574 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005575#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005576#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005577#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005578
Victor Stinner8c62be82010-05-06 00:08:46 +00005579 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005580
Fred Drake8cef4cf2000-06-28 16:40:38 +00005581}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005582#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005583
5584#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005585PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005586"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00005587Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
5588Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005589To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005590
5591static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005592posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005593{
Victor Stinner8c62be82010-05-06 00:08:46 +00005594 int master_fd = -1, result = 0;
5595 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005596
Victor Stinner8c62be82010-05-06 00:08:46 +00005597 _PyImport_AcquireLock();
5598 pid = forkpty(&master_fd, NULL, NULL, NULL);
5599 if (pid == 0) {
5600 /* child: this clobbers and resets the import lock. */
5601 PyOS_AfterFork();
5602 } else {
5603 /* parent: release the import lock. */
5604 result = _PyImport_ReleaseLock();
5605 }
5606 if (pid == -1)
5607 return posix_error();
5608 if (result < 0) {
5609 /* Don't clobber the OSError if the fork failed. */
5610 PyErr_SetString(PyExc_RuntimeError,
5611 "not holding the import lock");
5612 return NULL;
5613 }
5614 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005615}
5616#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005617
Ross Lagerwall7807c352011-03-17 20:20:30 +02005618
Guido van Rossumad0ee831995-03-01 10:34:45 +00005619#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005620PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005621"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005622Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005623
Barry Warsaw53699e91996-12-10 23:23:01 +00005624static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005625posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005626{
Victor Stinner8c62be82010-05-06 00:08:46 +00005627 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005628}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005629#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005630
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005631
Guido van Rossumad0ee831995-03-01 10:34:45 +00005632#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005633PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005634"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005635Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005636
Barry Warsaw53699e91996-12-10 23:23:01 +00005637static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005638posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005639{
Victor Stinner8c62be82010-05-06 00:08:46 +00005640 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005641}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005642#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005643
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005644
Guido van Rossumad0ee831995-03-01 10:34:45 +00005645#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005646PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005647"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005648Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005649
Barry Warsaw53699e91996-12-10 23:23:01 +00005650static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005651posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005652{
Victor Stinner8c62be82010-05-06 00:08:46 +00005653 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005654}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005655#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005656
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005657
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005658PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005659"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005660Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005661
Barry Warsaw53699e91996-12-10 23:23:01 +00005662static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005663posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005664{
Victor Stinner8c62be82010-05-06 00:08:46 +00005665 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005666}
5667
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005668#ifdef HAVE_GETGROUPLIST
5669PyDoc_STRVAR(posix_getgrouplist__doc__,
5670"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5671Returns a list of groups to which a user belongs.\n\n\
5672 user: username to lookup\n\
5673 group: base group id of the user");
5674
5675static PyObject *
5676posix_getgrouplist(PyObject *self, PyObject *args)
5677{
5678#ifdef NGROUPS_MAX
5679#define MAX_GROUPS NGROUPS_MAX
5680#else
5681 /* defined to be 16 on Solaris7, so this should be a small number */
5682#define MAX_GROUPS 64
5683#endif
5684
5685 const char *user;
5686 int i, ngroups;
5687 PyObject *list;
5688#ifdef __APPLE__
5689 int *groups, basegid;
5690#else
5691 gid_t *groups, basegid;
5692#endif
5693 ngroups = MAX_GROUPS;
5694
5695 if (!PyArg_ParseTuple(args, "si", &user, &basegid))
5696 return NULL;
5697
5698#ifdef __APPLE__
5699 groups = PyMem_Malloc(ngroups * sizeof(int));
5700#else
5701 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
5702#endif
5703 if (groups == NULL)
5704 return PyErr_NoMemory();
5705
5706 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
5707 PyMem_Del(groups);
5708 return posix_error();
5709 }
5710
5711 list = PyList_New(ngroups);
5712 if (list == NULL) {
5713 PyMem_Del(groups);
5714 return NULL;
5715 }
5716
5717 for (i = 0; i < ngroups; i++) {
5718 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
5719 if (o == NULL) {
5720 Py_DECREF(list);
5721 PyMem_Del(groups);
5722 return NULL;
5723 }
5724 PyList_SET_ITEM(list, i, o);
5725 }
5726
5727 PyMem_Del(groups);
5728
5729 return list;
5730}
5731#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005732
Fred Drakec9680921999-12-13 16:37:25 +00005733#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005734PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005735"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005736Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00005737
5738static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005739posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00005740{
5741 PyObject *result = NULL;
5742
Fred Drakec9680921999-12-13 16:37:25 +00005743#ifdef NGROUPS_MAX
5744#define MAX_GROUPS NGROUPS_MAX
5745#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005746 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00005747#define MAX_GROUPS 64
5748#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005749 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005750
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005751 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005752 * This is a helper variable to store the intermediate result when
5753 * that happens.
5754 *
5755 * To keep the code readable the OSX behaviour is unconditional,
5756 * according to the POSIX spec this should be safe on all unix-y
5757 * systems.
5758 */
5759 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005760 int n;
Fred Drakec9680921999-12-13 16:37:25 +00005761
Victor Stinner8c62be82010-05-06 00:08:46 +00005762 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005763 if (n < 0) {
5764 if (errno == EINVAL) {
5765 n = getgroups(0, NULL);
5766 if (n == -1) {
5767 return posix_error();
5768 }
5769 if (n == 0) {
5770 /* Avoid malloc(0) */
5771 alt_grouplist = grouplist;
5772 } else {
5773 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
5774 if (alt_grouplist == NULL) {
5775 errno = EINVAL;
5776 return posix_error();
5777 }
5778 n = getgroups(n, alt_grouplist);
5779 if (n == -1) {
5780 PyMem_Free(alt_grouplist);
5781 return posix_error();
5782 }
5783 }
5784 } else {
5785 return posix_error();
5786 }
5787 }
5788 result = PyList_New(n);
5789 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005790 int i;
5791 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005792 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00005793 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00005794 Py_DECREF(result);
5795 result = NULL;
5796 break;
Fred Drakec9680921999-12-13 16:37:25 +00005797 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005798 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00005799 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005800 }
5801
5802 if (alt_grouplist != grouplist) {
5803 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005804 }
Neal Norwitze241ce82003-02-17 18:17:05 +00005805
Fred Drakec9680921999-12-13 16:37:25 +00005806 return result;
5807}
5808#endif
5809
Antoine Pitroub7572f02009-12-02 20:46:48 +00005810#ifdef HAVE_INITGROUPS
5811PyDoc_STRVAR(posix_initgroups__doc__,
5812"initgroups(username, gid) -> None\n\n\
5813Call the system initgroups() to initialize the group access list with all of\n\
5814the groups of which the specified username is a member, plus the specified\n\
5815group id.");
5816
5817static PyObject *
5818posix_initgroups(PyObject *self, PyObject *args)
5819{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005820 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00005821 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005822 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00005823 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005824
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005825 if (!PyArg_ParseTuple(args, "O&l:initgroups",
5826 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00005827 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005828 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005829
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005830 res = initgroups(username, (gid_t) gid);
5831 Py_DECREF(oname);
5832 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00005833 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005834
Victor Stinner8c62be82010-05-06 00:08:46 +00005835 Py_INCREF(Py_None);
5836 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005837}
5838#endif
5839
Martin v. Löwis606edc12002-06-13 21:09:11 +00005840#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005841PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005842"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005843Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00005844
5845static PyObject *
5846posix_getpgid(PyObject *self, PyObject *args)
5847{
Victor Stinner8c62be82010-05-06 00:08:46 +00005848 pid_t pid, pgid;
5849 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
5850 return NULL;
5851 pgid = getpgid(pid);
5852 if (pgid < 0)
5853 return posix_error();
5854 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00005855}
5856#endif /* HAVE_GETPGID */
5857
5858
Guido van Rossumb6775db1994-08-01 11:34:53 +00005859#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005860PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005861"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005862Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005863
Barry Warsaw53699e91996-12-10 23:23:01 +00005864static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005865posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00005866{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005867#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005868 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005869#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005870 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005871#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00005872}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005873#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00005874
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005875
Guido van Rossumb6775db1994-08-01 11:34:53 +00005876#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005877PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005878"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00005879Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005880
Barry Warsaw53699e91996-12-10 23:23:01 +00005881static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005882posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005883{
Guido van Rossum64933891994-10-20 21:56:42 +00005884#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005885 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005886#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005887 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005888#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005889 return posix_error();
5890 Py_INCREF(Py_None);
5891 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005892}
5893
Guido van Rossumb6775db1994-08-01 11:34:53 +00005894#endif /* HAVE_SETPGRP */
5895
Guido van Rossumad0ee831995-03-01 10:34:45 +00005896#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005897
5898#ifdef MS_WINDOWS
5899#include <tlhelp32.h>
5900
5901static PyObject*
5902win32_getppid()
5903{
5904 HANDLE snapshot;
5905 pid_t mypid;
5906 PyObject* result = NULL;
5907 BOOL have_record;
5908 PROCESSENTRY32 pe;
5909
5910 mypid = getpid(); /* This function never fails */
5911
5912 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
5913 if (snapshot == INVALID_HANDLE_VALUE)
5914 return PyErr_SetFromWindowsErr(GetLastError());
5915
5916 pe.dwSize = sizeof(pe);
5917 have_record = Process32First(snapshot, &pe);
5918 while (have_record) {
5919 if (mypid == (pid_t)pe.th32ProcessID) {
5920 /* We could cache the ulong value in a static variable. */
5921 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
5922 break;
5923 }
5924
5925 have_record = Process32Next(snapshot, &pe);
5926 }
5927
5928 /* If our loop exits and our pid was not found (result will be NULL)
5929 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
5930 * error anyway, so let's raise it. */
5931 if (!result)
5932 result = PyErr_SetFromWindowsErr(GetLastError());
5933
5934 CloseHandle(snapshot);
5935
5936 return result;
5937}
5938#endif /*MS_WINDOWS*/
5939
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005940PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005941"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005942Return the parent's process id. If the parent process has already exited,\n\
5943Windows machines will still return its id; others systems will return the id\n\
5944of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005945
Barry Warsaw53699e91996-12-10 23:23:01 +00005946static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005947posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005948{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005949#ifdef MS_WINDOWS
5950 return win32_getppid();
5951#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005952 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00005953#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005954}
5955#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005956
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005957
Fred Drake12c6e2d1999-12-14 21:25:03 +00005958#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005959PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005960"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005961Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00005962
5963static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005964posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005965{
Victor Stinner8c62be82010-05-06 00:08:46 +00005966 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005967#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005968 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02005969 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005970
5971 if (GetUserNameW(user_name, &num_chars)) {
5972 /* num_chars is the number of unicode chars plus null terminator */
5973 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005974 }
5975 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005976 result = PyErr_SetFromWindowsErr(GetLastError());
5977#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005978 char *name;
5979 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005980
Victor Stinner8c62be82010-05-06 00:08:46 +00005981 errno = 0;
5982 name = getlogin();
5983 if (name == NULL) {
5984 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00005985 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00005986 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00005987 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00005988 }
5989 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00005990 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00005991 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005992#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00005993 return result;
5994}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005995#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005996
Guido van Rossumad0ee831995-03-01 10:34:45 +00005997#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005998PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005999"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006000Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006001
Barry Warsaw53699e91996-12-10 23:23:01 +00006002static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006003posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006004{
Victor Stinner8c62be82010-05-06 00:08:46 +00006005 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006006}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006007#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006008
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006009
Guido van Rossumad0ee831995-03-01 10:34:45 +00006010#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006011PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006012"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006013Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006014
Barry Warsaw53699e91996-12-10 23:23:01 +00006015static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006016posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006017{
Victor Stinner8c62be82010-05-06 00:08:46 +00006018 pid_t pid;
6019 int sig;
6020 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6021 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006022 if (kill(pid, sig) == -1)
6023 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006024 Py_INCREF(Py_None);
6025 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006026}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006027#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006028
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006029#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006030PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006031"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006032Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006033
6034static PyObject *
6035posix_killpg(PyObject *self, PyObject *args)
6036{
Victor Stinner8c62be82010-05-06 00:08:46 +00006037 int sig;
6038 pid_t pgid;
6039 /* XXX some man pages make the `pgid` parameter an int, others
6040 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6041 take the same type. Moreover, pid_t is always at least as wide as
6042 int (else compilation of this module fails), which is safe. */
6043 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6044 return NULL;
6045 if (killpg(pgid, sig) == -1)
6046 return posix_error();
6047 Py_INCREF(Py_None);
6048 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006049}
6050#endif
6051
Brian Curtineb24d742010-04-12 17:16:38 +00006052#ifdef MS_WINDOWS
6053PyDoc_STRVAR(win32_kill__doc__,
6054"kill(pid, sig)\n\n\
6055Kill a process with a signal.");
6056
6057static PyObject *
6058win32_kill(PyObject *self, PyObject *args)
6059{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006060 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00006061 DWORD pid, sig, err;
6062 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006063
Victor Stinner8c62be82010-05-06 00:08:46 +00006064 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
6065 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006066
Victor Stinner8c62be82010-05-06 00:08:46 +00006067 /* Console processes which share a common console can be sent CTRL+C or
6068 CTRL+BREAK events, provided they handle said events. */
6069 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
6070 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
6071 err = GetLastError();
6072 PyErr_SetFromWindowsErr(err);
6073 }
6074 else
6075 Py_RETURN_NONE;
6076 }
Brian Curtineb24d742010-04-12 17:16:38 +00006077
Victor Stinner8c62be82010-05-06 00:08:46 +00006078 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6079 attempt to open and terminate the process. */
6080 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
6081 if (handle == NULL) {
6082 err = GetLastError();
6083 return PyErr_SetFromWindowsErr(err);
6084 }
Brian Curtineb24d742010-04-12 17:16:38 +00006085
Victor Stinner8c62be82010-05-06 00:08:46 +00006086 if (TerminateProcess(handle, sig) == 0) {
6087 err = GetLastError();
6088 result = PyErr_SetFromWindowsErr(err);
6089 } else {
6090 Py_INCREF(Py_None);
6091 result = Py_None;
6092 }
Brian Curtineb24d742010-04-12 17:16:38 +00006093
Victor Stinner8c62be82010-05-06 00:08:46 +00006094 CloseHandle(handle);
6095 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006096}
6097#endif /* MS_WINDOWS */
6098
Guido van Rossumc0125471996-06-28 18:55:32 +00006099#ifdef HAVE_PLOCK
6100
6101#ifdef HAVE_SYS_LOCK_H
6102#include <sys/lock.h>
6103#endif
6104
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006105PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006106"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006107Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006108
Barry Warsaw53699e91996-12-10 23:23:01 +00006109static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006110posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006111{
Victor Stinner8c62be82010-05-06 00:08:46 +00006112 int op;
6113 if (!PyArg_ParseTuple(args, "i:plock", &op))
6114 return NULL;
6115 if (plock(op) == -1)
6116 return posix_error();
6117 Py_INCREF(Py_None);
6118 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006119}
6120#endif
6121
Guido van Rossumb6775db1994-08-01 11:34:53 +00006122#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006123PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006124"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006125Set the current process's user id.");
6126
Barry Warsaw53699e91996-12-10 23:23:01 +00006127static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006128posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006129{
Victor Stinner8c62be82010-05-06 00:08:46 +00006130 long uid_arg;
6131 uid_t uid;
6132 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
6133 return NULL;
6134 uid = uid_arg;
6135 if (uid != uid_arg) {
6136 PyErr_SetString(PyExc_OverflowError, "user id too big");
6137 return NULL;
6138 }
6139 if (setuid(uid) < 0)
6140 return posix_error();
6141 Py_INCREF(Py_None);
6142 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006143}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006144#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006145
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006146
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006147#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006148PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006149"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006150Set the current process's effective user id.");
6151
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006152static PyObject *
6153posix_seteuid (PyObject *self, PyObject *args)
6154{
Victor Stinner8c62be82010-05-06 00:08:46 +00006155 long euid_arg;
6156 uid_t euid;
6157 if (!PyArg_ParseTuple(args, "l", &euid_arg))
6158 return NULL;
6159 euid = euid_arg;
6160 if (euid != euid_arg) {
6161 PyErr_SetString(PyExc_OverflowError, "user id too big");
6162 return NULL;
6163 }
6164 if (seteuid(euid) < 0) {
6165 return posix_error();
6166 } else {
6167 Py_INCREF(Py_None);
6168 return Py_None;
6169 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006170}
6171#endif /* HAVE_SETEUID */
6172
6173#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006174PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006175"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006176Set the current process's effective group id.");
6177
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006178static PyObject *
6179posix_setegid (PyObject *self, PyObject *args)
6180{
Victor Stinner8c62be82010-05-06 00:08:46 +00006181 long egid_arg;
6182 gid_t egid;
6183 if (!PyArg_ParseTuple(args, "l", &egid_arg))
6184 return NULL;
6185 egid = egid_arg;
6186 if (egid != egid_arg) {
6187 PyErr_SetString(PyExc_OverflowError, "group id too big");
6188 return NULL;
6189 }
6190 if (setegid(egid) < 0) {
6191 return posix_error();
6192 } else {
6193 Py_INCREF(Py_None);
6194 return Py_None;
6195 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006196}
6197#endif /* HAVE_SETEGID */
6198
6199#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006200PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006201"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006202Set the current process's real and effective user ids.");
6203
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006204static PyObject *
6205posix_setreuid (PyObject *self, PyObject *args)
6206{
Victor Stinner8c62be82010-05-06 00:08:46 +00006207 long ruid_arg, euid_arg;
6208 uid_t ruid, euid;
6209 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
6210 return NULL;
6211 if (ruid_arg == -1)
6212 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
6213 else
6214 ruid = ruid_arg; /* otherwise, assign from our long */
6215 if (euid_arg == -1)
6216 euid = (uid_t)-1;
6217 else
6218 euid = euid_arg;
6219 if ((euid_arg != -1 && euid != euid_arg) ||
6220 (ruid_arg != -1 && ruid != ruid_arg)) {
6221 PyErr_SetString(PyExc_OverflowError, "user id too big");
6222 return NULL;
6223 }
6224 if (setreuid(ruid, euid) < 0) {
6225 return posix_error();
6226 } else {
6227 Py_INCREF(Py_None);
6228 return Py_None;
6229 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006230}
6231#endif /* HAVE_SETREUID */
6232
6233#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006234PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006235"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006236Set the current process's real and effective group ids.");
6237
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006238static PyObject *
6239posix_setregid (PyObject *self, PyObject *args)
6240{
Victor Stinner8c62be82010-05-06 00:08:46 +00006241 long rgid_arg, egid_arg;
6242 gid_t rgid, egid;
6243 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
6244 return NULL;
6245 if (rgid_arg == -1)
6246 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
6247 else
6248 rgid = rgid_arg; /* otherwise, assign from our long */
6249 if (egid_arg == -1)
6250 egid = (gid_t)-1;
6251 else
6252 egid = egid_arg;
6253 if ((egid_arg != -1 && egid != egid_arg) ||
6254 (rgid_arg != -1 && rgid != rgid_arg)) {
6255 PyErr_SetString(PyExc_OverflowError, "group id too big");
6256 return NULL;
6257 }
6258 if (setregid(rgid, egid) < 0) {
6259 return posix_error();
6260 } else {
6261 Py_INCREF(Py_None);
6262 return Py_None;
6263 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006264}
6265#endif /* HAVE_SETREGID */
6266
Guido van Rossumb6775db1994-08-01 11:34:53 +00006267#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006268PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006269"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006270Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006271
Barry Warsaw53699e91996-12-10 23:23:01 +00006272static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006273posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006274{
Victor Stinner8c62be82010-05-06 00:08:46 +00006275 long gid_arg;
6276 gid_t gid;
6277 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
6278 return NULL;
6279 gid = gid_arg;
6280 if (gid != gid_arg) {
6281 PyErr_SetString(PyExc_OverflowError, "group id too big");
6282 return NULL;
6283 }
6284 if (setgid(gid) < 0)
6285 return posix_error();
6286 Py_INCREF(Py_None);
6287 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006288}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006289#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006290
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006291#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006292PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006293"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006294Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006295
6296static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006297posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006298{
Victor Stinner8c62be82010-05-06 00:08:46 +00006299 int i, len;
6300 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006301
Victor Stinner8c62be82010-05-06 00:08:46 +00006302 if (!PySequence_Check(groups)) {
6303 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6304 return NULL;
6305 }
6306 len = PySequence_Size(groups);
6307 if (len > MAX_GROUPS) {
6308 PyErr_SetString(PyExc_ValueError, "too many groups");
6309 return NULL;
6310 }
6311 for(i = 0; i < len; i++) {
6312 PyObject *elem;
6313 elem = PySequence_GetItem(groups, i);
6314 if (!elem)
6315 return NULL;
6316 if (!PyLong_Check(elem)) {
6317 PyErr_SetString(PyExc_TypeError,
6318 "groups must be integers");
6319 Py_DECREF(elem);
6320 return NULL;
6321 } else {
6322 unsigned long x = PyLong_AsUnsignedLong(elem);
6323 if (PyErr_Occurred()) {
6324 PyErr_SetString(PyExc_TypeError,
6325 "group id too big");
6326 Py_DECREF(elem);
6327 return NULL;
6328 }
6329 grouplist[i] = x;
6330 /* read back the value to see if it fitted in gid_t */
6331 if (grouplist[i] != x) {
6332 PyErr_SetString(PyExc_TypeError,
6333 "group id too big");
6334 Py_DECREF(elem);
6335 return NULL;
6336 }
6337 }
6338 Py_DECREF(elem);
6339 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006340
Victor Stinner8c62be82010-05-06 00:08:46 +00006341 if (setgroups(len, grouplist) < 0)
6342 return posix_error();
6343 Py_INCREF(Py_None);
6344 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006345}
6346#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006347
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006348#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6349static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006350wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006351{
Victor Stinner8c62be82010-05-06 00:08:46 +00006352 PyObject *result;
6353 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006354 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006355
Victor Stinner8c62be82010-05-06 00:08:46 +00006356 if (pid == -1)
6357 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006358
Victor Stinner8c62be82010-05-06 00:08:46 +00006359 if (struct_rusage == NULL) {
6360 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6361 if (m == NULL)
6362 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006363 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006364 Py_DECREF(m);
6365 if (struct_rusage == NULL)
6366 return NULL;
6367 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006368
Victor Stinner8c62be82010-05-06 00:08:46 +00006369 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6370 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6371 if (!result)
6372 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006373
6374#ifndef doubletime
6375#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6376#endif
6377
Victor Stinner8c62be82010-05-06 00:08:46 +00006378 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006379 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006380 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006381 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006382#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006383 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6384 SET_INT(result, 2, ru->ru_maxrss);
6385 SET_INT(result, 3, ru->ru_ixrss);
6386 SET_INT(result, 4, ru->ru_idrss);
6387 SET_INT(result, 5, ru->ru_isrss);
6388 SET_INT(result, 6, ru->ru_minflt);
6389 SET_INT(result, 7, ru->ru_majflt);
6390 SET_INT(result, 8, ru->ru_nswap);
6391 SET_INT(result, 9, ru->ru_inblock);
6392 SET_INT(result, 10, ru->ru_oublock);
6393 SET_INT(result, 11, ru->ru_msgsnd);
6394 SET_INT(result, 12, ru->ru_msgrcv);
6395 SET_INT(result, 13, ru->ru_nsignals);
6396 SET_INT(result, 14, ru->ru_nvcsw);
6397 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006398#undef SET_INT
6399
Victor Stinner8c62be82010-05-06 00:08:46 +00006400 if (PyErr_Occurred()) {
6401 Py_DECREF(result);
6402 return NULL;
6403 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006404
Victor Stinner8c62be82010-05-06 00:08:46 +00006405 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006406}
6407#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6408
6409#ifdef HAVE_WAIT3
6410PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006411"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006412Wait for completion of a child process.");
6413
6414static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006415posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006416{
Victor Stinner8c62be82010-05-06 00:08:46 +00006417 pid_t pid;
6418 int options;
6419 struct rusage ru;
6420 WAIT_TYPE status;
6421 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006422
Victor Stinner4195b5c2012-02-08 23:03:19 +01006423 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006424 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006425
Victor Stinner8c62be82010-05-06 00:08:46 +00006426 Py_BEGIN_ALLOW_THREADS
6427 pid = wait3(&status, options, &ru);
6428 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006429
Victor Stinner4195b5c2012-02-08 23:03:19 +01006430 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006431}
6432#endif /* HAVE_WAIT3 */
6433
6434#ifdef HAVE_WAIT4
6435PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006436"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006437Wait for completion of a given child process.");
6438
6439static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006440posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006441{
Victor Stinner8c62be82010-05-06 00:08:46 +00006442 pid_t pid;
6443 int options;
6444 struct rusage ru;
6445 WAIT_TYPE status;
6446 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006447
Victor Stinner4195b5c2012-02-08 23:03:19 +01006448 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006449 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006450
Victor Stinner8c62be82010-05-06 00:08:46 +00006451 Py_BEGIN_ALLOW_THREADS
6452 pid = wait4(pid, &status, options, &ru);
6453 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006454
Victor Stinner4195b5c2012-02-08 23:03:19 +01006455 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006456}
6457#endif /* HAVE_WAIT4 */
6458
Ross Lagerwall7807c352011-03-17 20:20:30 +02006459#if defined(HAVE_WAITID) && !defined(__APPLE__)
6460PyDoc_STRVAR(posix_waitid__doc__,
6461"waitid(idtype, id, options) -> waitid_result\n\n\
6462Wait for the completion of one or more child processes.\n\n\
6463idtype can be P_PID, P_PGID or P_ALL.\n\
6464id specifies the pid to wait on.\n\
6465options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6466or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6467Returns either waitid_result or None if WNOHANG is specified and there are\n\
6468no children in a waitable state.");
6469
6470static PyObject *
6471posix_waitid(PyObject *self, PyObject *args)
6472{
6473 PyObject *result;
6474 idtype_t idtype;
6475 id_t id;
6476 int options, res;
6477 siginfo_t si;
6478 si.si_pid = 0;
6479 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6480 return NULL;
6481 Py_BEGIN_ALLOW_THREADS
6482 res = waitid(idtype, id, &si, options);
6483 Py_END_ALLOW_THREADS
6484 if (res == -1)
6485 return posix_error();
6486
6487 if (si.si_pid == 0)
6488 Py_RETURN_NONE;
6489
6490 result = PyStructSequence_New(&WaitidResultType);
6491 if (!result)
6492 return NULL;
6493
6494 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
6495 PyStructSequence_SET_ITEM(result, 1, PyLong_FromPid(si.si_uid));
6496 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6497 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6498 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6499 if (PyErr_Occurred()) {
6500 Py_DECREF(result);
6501 return NULL;
6502 }
6503
6504 return result;
6505}
6506#endif
6507
Guido van Rossumb6775db1994-08-01 11:34:53 +00006508#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006509PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006510"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006511Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006512
Barry Warsaw53699e91996-12-10 23:23:01 +00006513static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006514posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006515{
Victor Stinner8c62be82010-05-06 00:08:46 +00006516 pid_t pid;
6517 int options;
6518 WAIT_TYPE status;
6519 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006520
Victor Stinner8c62be82010-05-06 00:08:46 +00006521 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6522 return NULL;
6523 Py_BEGIN_ALLOW_THREADS
6524 pid = waitpid(pid, &status, options);
6525 Py_END_ALLOW_THREADS
6526 if (pid == -1)
6527 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006528
Victor Stinner8c62be82010-05-06 00:08:46 +00006529 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006530}
6531
Tim Petersab034fa2002-02-01 11:27:43 +00006532#elif defined(HAVE_CWAIT)
6533
6534/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006535PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006536"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006537"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006538
6539static PyObject *
6540posix_waitpid(PyObject *self, PyObject *args)
6541{
Victor Stinner8c62be82010-05-06 00:08:46 +00006542 Py_intptr_t pid;
6543 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006544
Victor Stinner8c62be82010-05-06 00:08:46 +00006545 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6546 return NULL;
6547 Py_BEGIN_ALLOW_THREADS
6548 pid = _cwait(&status, pid, options);
6549 Py_END_ALLOW_THREADS
6550 if (pid == -1)
6551 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006552
Victor Stinner8c62be82010-05-06 00:08:46 +00006553 /* shift the status left a byte so this is more like the POSIX waitpid */
6554 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006555}
6556#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006557
Guido van Rossumad0ee831995-03-01 10:34:45 +00006558#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006559PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006560"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006561Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006562
Barry Warsaw53699e91996-12-10 23:23:01 +00006563static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006564posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006565{
Victor Stinner8c62be82010-05-06 00:08:46 +00006566 pid_t pid;
6567 WAIT_TYPE status;
6568 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006569
Victor Stinner8c62be82010-05-06 00:08:46 +00006570 Py_BEGIN_ALLOW_THREADS
6571 pid = wait(&status);
6572 Py_END_ALLOW_THREADS
6573 if (pid == -1)
6574 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006575
Victor Stinner8c62be82010-05-06 00:08:46 +00006576 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006577}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006578#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006579
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006580
Larry Hastings9cf065c2012-06-22 16:30:09 -07006581#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
6582PyDoc_STRVAR(readlink__doc__,
6583"readlink(path, *, dir_fd=None) -> path\n\n\
6584Return a string representing the path to which the symbolic link points.\n\
6585\n\
6586If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6587 and path should be relative; path will then be relative to that directory.\n\
6588dir_fd may not be implemented on your platform.\n\
6589 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006590#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006591
Guido van Rossumb6775db1994-08-01 11:34:53 +00006592#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006593
Barry Warsaw53699e91996-12-10 23:23:01 +00006594static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006595posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006596{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006597 path_t path;
6598 int dir_fd = DEFAULT_DIR_FD;
6599 char buffer[MAXPATHLEN];
6600 ssize_t length;
6601 PyObject *return_value = NULL;
6602 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00006603
Larry Hastings9cf065c2012-06-22 16:30:09 -07006604 memset(&path, 0, sizeof(path));
6605 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
6606 path_converter, &path,
6607#ifdef HAVE_READLINKAT
6608 dir_fd_converter, &dir_fd
6609#else
6610 dir_fd_unavailable, &dir_fd
6611#endif
6612 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00006613 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00006614
Victor Stinner8c62be82010-05-06 00:08:46 +00006615 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07006616#ifdef HAVE_READLINKAT
6617 if (dir_fd != DEFAULT_DIR_FD)
6618 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00006619 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07006620#endif
6621 length = readlink(path.narrow, buffer, sizeof(buffer));
6622 Py_END_ALLOW_THREADS
6623
6624 if (length < 0) {
6625 return_value = path_posix_error("readlink", &path);
6626 goto exit;
6627 }
6628
6629 if (PyUnicode_Check(path.object))
6630 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
6631 else
6632 return_value = PyBytes_FromStringAndSize(buffer, length);
6633exit:
6634 path_cleanup(&path);
6635 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006636}
Larry Hastings9cf065c2012-06-22 16:30:09 -07006637
6638
Guido van Rossumb6775db1994-08-01 11:34:53 +00006639#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006640
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006641
Larry Hastings9cf065c2012-06-22 16:30:09 -07006642#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006643PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07006644"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
6645Create a symbolic link pointing to src named dst.\n\n\
6646target_is_directory is required on Windows if the target is to be\n\
6647 interpreted as a directory. (On Windows, symlink requires\n\
6648 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
6649 target_is_directory is ignored on non-Windows platforms.\n\
6650\n\
6651If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6652 and path should be relative; path will then be relative to that directory.\n\
6653dir_fd may not be implemented on your platform.\n\
6654 If it is unavailable, using it will raise a NotImplementedError.");
6655
6656#if defined(MS_WINDOWS)
6657
6658/* Grab CreateSymbolicLinkW dynamically from kernel32 */
6659static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
6660static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
6661static int
6662check_CreateSymbolicLink()
6663{
6664 HINSTANCE hKernel32;
6665 /* only recheck */
6666 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
6667 return 1;
6668 hKernel32 = GetModuleHandleW(L"KERNEL32");
6669 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
6670 "CreateSymbolicLinkW");
6671 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
6672 "CreateSymbolicLinkA");
6673 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
6674}
6675
6676#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006677
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006678static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006679posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006680{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006681 path_t src;
6682 path_t dst;
6683 int dir_fd = DEFAULT_DIR_FD;
6684 int target_is_directory = 0;
6685 static char *keywords[] = {"src", "dst", "target_is_directory",
6686 "dir_fd", NULL};
6687 PyObject *return_value;
6688#ifdef MS_WINDOWS
6689 DWORD result;
6690#else
6691 int result;
6692#endif
6693
6694 memset(&src, 0, sizeof(src));
6695 src.argument_name = "src";
6696 memset(&dst, 0, sizeof(dst));
6697 dst.argument_name = "dst";
6698
6699#ifdef MS_WINDOWS
6700 if (!check_CreateSymbolicLink()) {
6701 PyErr_SetString(PyExc_NotImplementedError,
6702 "CreateSymbolicLink functions not found");
6703 return NULL;
6704 }
6705 if (!win32_can_symlink) {
6706 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
6707 return NULL;
6708 }
6709#endif
6710
6711 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
6712 keywords,
6713 path_converter, &src,
6714 path_converter, &dst,
6715 &target_is_directory,
6716#ifdef HAVE_SYMLINKAT
6717 dir_fd_converter, &dir_fd
6718#else
6719 dir_fd_unavailable, &dir_fd
6720#endif
6721 ))
6722 return NULL;
6723
6724 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
6725 PyErr_SetString(PyExc_ValueError,
6726 "symlink: src and dst must be the same type");
6727 return_value = NULL;
6728 goto exit;
6729 }
6730
6731#ifdef MS_WINDOWS
6732 Py_BEGIN_ALLOW_THREADS
6733 if (dst.wide)
6734 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
6735 target_is_directory);
6736 else
6737 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
6738 target_is_directory);
6739 Py_END_ALLOW_THREADS
6740
6741 if (!result) {
6742 return_value = win32_error_object("symlink", src.object);
6743 goto exit;
6744 }
6745
6746#else
6747
6748 Py_BEGIN_ALLOW_THREADS
6749#if HAVE_SYMLINKAT
6750 if (dir_fd != DEFAULT_DIR_FD)
6751 result = symlinkat(src.narrow, dir_fd, dst.narrow);
6752 else
6753#endif
6754 result = symlink(src.narrow, dst.narrow);
6755 Py_END_ALLOW_THREADS
6756
6757 if (result) {
6758 return_value = path_error("symlink", &dst);
6759 goto exit;
6760 }
6761#endif
6762
6763 return_value = Py_None;
6764 Py_INCREF(Py_None);
6765 goto exit; /* silence "unused label" warning */
6766exit:
6767 path_cleanup(&src);
6768 path_cleanup(&dst);
6769 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006770}
Larry Hastings9cf065c2012-06-22 16:30:09 -07006771
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006772#endif /* HAVE_SYMLINK */
6773
Larry Hastings9cf065c2012-06-22 16:30:09 -07006774
Brian Curtind40e6f72010-07-08 21:39:08 +00006775#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
6776
Brian Curtind40e6f72010-07-08 21:39:08 +00006777static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006778win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00006779{
6780 wchar_t *path;
6781 DWORD n_bytes_returned;
6782 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006783 PyObject *po, *result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07006784 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00006785 HANDLE reparse_point_handle;
6786
6787 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
6788 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
6789 wchar_t *print_name;
6790
Larry Hastings9cf065c2012-06-22 16:30:09 -07006791 static char *keywords[] = {"path", "dir_fd", NULL};
6792
6793 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
6794 &po,
6795 dir_fd_unavailable, &dir_fd
6796 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02006797 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07006798
Victor Stinnereb5657a2011-09-30 01:44:27 +02006799 path = PyUnicode_AsUnicode(po);
6800 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00006801 return NULL;
6802
6803 /* First get a handle to the reparse point */
6804 Py_BEGIN_ALLOW_THREADS
6805 reparse_point_handle = CreateFileW(
6806 path,
6807 0,
6808 0,
6809 0,
6810 OPEN_EXISTING,
6811 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
6812 0);
6813 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006814
Brian Curtind40e6f72010-07-08 21:39:08 +00006815 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006816 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006817
Brian Curtind40e6f72010-07-08 21:39:08 +00006818 Py_BEGIN_ALLOW_THREADS
6819 /* New call DeviceIoControl to read the reparse point */
6820 io_result = DeviceIoControl(
6821 reparse_point_handle,
6822 FSCTL_GET_REPARSE_POINT,
6823 0, 0, /* in buffer */
6824 target_buffer, sizeof(target_buffer),
6825 &n_bytes_returned,
6826 0 /* we're not using OVERLAPPED_IO */
6827 );
6828 CloseHandle(reparse_point_handle);
6829 Py_END_ALLOW_THREADS
6830
6831 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006832 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00006833
6834 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
6835 {
6836 PyErr_SetString(PyExc_ValueError,
6837 "not a symbolic link");
6838 return NULL;
6839 }
Brian Curtin74e45612010-07-09 15:58:59 +00006840 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
6841 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
6842
6843 result = PyUnicode_FromWideChar(print_name,
6844 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00006845 return result;
6846}
6847
6848#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
6849
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006850
Larry Hastings605a62d2012-06-24 04:33:36 -07006851static PyStructSequence_Field times_result_fields[] = {
6852 {"user", "user time"},
6853 {"system", "system time"},
6854 {"children_user", "user time of children"},
6855 {"children_system", "system time of children"},
6856 {"elapsed", "elapsed time since an arbitrary point in the past"},
6857 {NULL}
6858};
6859
6860PyDoc_STRVAR(times_result__doc__,
6861"times_result: Result from os.times().\n\n\
6862This object may be accessed either as a tuple of\n\
6863 (user, system, children_user, children_system, elapsed),\n\
6864or via the attributes user, system, children_user, children_system,\n\
6865and elapsed.\n\
6866\n\
6867See os.times for more information.");
6868
6869static PyStructSequence_Desc times_result_desc = {
6870 "times_result", /* name */
6871 times_result__doc__, /* doc */
6872 times_result_fields,
6873 5
6874};
6875
6876static PyTypeObject TimesResultType;
6877
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006878#ifdef MS_WINDOWS
6879#define HAVE_TIMES /* mandatory, for the method table */
6880#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07006881
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006882#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07006883
6884static PyObject *
6885build_times_result(double user, double system,
6886 double children_user, double children_system,
6887 double elapsed)
6888{
6889 PyObject *value = PyStructSequence_New(&TimesResultType);
6890 if (value == NULL)
6891 return NULL;
6892
6893#define SET(i, field) \
6894 { \
6895 PyObject *o = PyFloat_FromDouble(field); \
6896 if (!o) { \
6897 Py_DECREF(value); \
6898 return NULL; \
6899 } \
6900 PyStructSequence_SET_ITEM(value, i, o); \
6901 } \
6902
6903 SET(0, user);
6904 SET(1, system);
6905 SET(2, children_user);
6906 SET(3, children_system);
6907 SET(4, elapsed);
6908
6909#undef SET
6910
6911 return value;
6912}
6913
6914PyDoc_STRVAR(posix_times__doc__,
6915"times() -> times_result\n\n\
6916Return an object containing floating point numbers indicating process\n\
6917times. The object behaves like a named tuple with these fields:\n\
6918 (utime, stime, cutime, cstime, elapsed_time)");
6919
Jesus Ceaab70e2a2012-10-05 01:48:08 +02006920#if defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00006921static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006922posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006923{
Victor Stinner8c62be82010-05-06 00:08:46 +00006924 FILETIME create, exit, kernel, user;
6925 HANDLE hProc;
6926 hProc = GetCurrentProcess();
6927 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6928 /* The fields of a FILETIME structure are the hi and lo part
6929 of a 64-bit value expressed in 100 nanosecond units.
6930 1e7 is one second in such units; 1e-7 the inverse.
6931 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6932 */
Larry Hastings605a62d2012-06-24 04:33:36 -07006933 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00006934 (double)(user.dwHighDateTime*429.4967296 +
6935 user.dwLowDateTime*1e-7),
6936 (double)(kernel.dwHighDateTime*429.4967296 +
6937 kernel.dwLowDateTime*1e-7),
6938 (double)0,
6939 (double)0,
6940 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006941}
Jesus Ceaab70e2a2012-10-05 01:48:08 +02006942#else /* Not Windows */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006943#define NEED_TICKS_PER_SECOND
6944static long ticks_per_second = -1;
6945static PyObject *
6946posix_times(PyObject *self, PyObject *noargs)
6947{
6948 struct tms t;
6949 clock_t c;
6950 errno = 0;
6951 c = times(&t);
6952 if (c == (clock_t) -1)
6953 return posix_error();
6954 return build_times_result(
6955 (double)t.tms_utime / ticks_per_second,
6956 (double)t.tms_stime / ticks_per_second,
6957 (double)t.tms_cutime / ticks_per_second,
6958 (double)t.tms_cstime / ticks_per_second,
6959 (double)c / ticks_per_second);
6960}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006961#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006962
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006963#endif /* HAVE_TIMES */
6964
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006965
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006966#ifdef HAVE_GETSID
6967PyDoc_STRVAR(posix_getsid__doc__,
6968"getsid(pid) -> sid\n\n\
6969Call the system call getsid().");
6970
6971static PyObject *
6972posix_getsid(PyObject *self, PyObject *args)
6973{
Victor Stinner8c62be82010-05-06 00:08:46 +00006974 pid_t pid;
6975 int sid;
6976 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
6977 return NULL;
6978 sid = getsid(pid);
6979 if (sid < 0)
6980 return posix_error();
6981 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006982}
6983#endif /* HAVE_GETSID */
6984
6985
Guido van Rossumb6775db1994-08-01 11:34:53 +00006986#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006987PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006988"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006989Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006990
Barry Warsaw53699e91996-12-10 23:23:01 +00006991static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006992posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006993{
Victor Stinner8c62be82010-05-06 00:08:46 +00006994 if (setsid() < 0)
6995 return posix_error();
6996 Py_INCREF(Py_None);
6997 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006998}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006999#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007000
Guido van Rossumb6775db1994-08-01 11:34:53 +00007001#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007002PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007003"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007004Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007005
Barry Warsaw53699e91996-12-10 23:23:01 +00007006static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007007posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007008{
Victor Stinner8c62be82010-05-06 00:08:46 +00007009 pid_t pid;
7010 int pgrp;
7011 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7012 return NULL;
7013 if (setpgid(pid, pgrp) < 0)
7014 return posix_error();
7015 Py_INCREF(Py_None);
7016 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007017}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007018#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007019
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007020
Guido van Rossumb6775db1994-08-01 11:34:53 +00007021#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007022PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007023"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007024Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007025
Barry Warsaw53699e91996-12-10 23:23:01 +00007026static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007027posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007028{
Victor Stinner8c62be82010-05-06 00:08:46 +00007029 int fd;
7030 pid_t pgid;
7031 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7032 return NULL;
7033 pgid = tcgetpgrp(fd);
7034 if (pgid < 0)
7035 return posix_error();
7036 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007037}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007038#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007039
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007040
Guido van Rossumb6775db1994-08-01 11:34:53 +00007041#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007042PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007043"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007044Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007045
Barry Warsaw53699e91996-12-10 23:23:01 +00007046static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007047posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007048{
Victor Stinner8c62be82010-05-06 00:08:46 +00007049 int fd;
7050 pid_t pgid;
7051 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7052 return NULL;
7053 if (tcsetpgrp(fd, pgid) < 0)
7054 return posix_error();
7055 Py_INCREF(Py_None);
7056 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007057}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007058#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007059
Guido van Rossum687dd131993-05-17 08:34:16 +00007060/* Functions acting on file descriptors */
7061
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007062PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007063"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7064Open a file for low level IO. Returns a file handle (integer).\n\
7065\n\
7066If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7067 and path should be relative; path will then be relative to that directory.\n\
7068dir_fd may not be implemented on your platform.\n\
7069 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007070
Barry Warsaw53699e91996-12-10 23:23:01 +00007071static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007072posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007073{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007074 path_t path;
7075 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007076 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007077 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007078 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007079 PyObject *return_value = NULL;
7080 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007081
Larry Hastings9cf065c2012-06-22 16:30:09 -07007082 memset(&path, 0, sizeof(path));
7083 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7084 path_converter, &path,
7085 &flags, &mode,
7086#ifdef HAVE_OPENAT
7087 dir_fd_converter, &dir_fd
7088#else
7089 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007090#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007091 ))
7092 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007093
Victor Stinner8c62be82010-05-06 00:08:46 +00007094 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007095#ifdef MS_WINDOWS
7096 if (path.wide)
7097 fd = _wopen(path.wide, flags, mode);
7098 else
7099#endif
7100#ifdef HAVE_OPENAT
7101 if (dir_fd != DEFAULT_DIR_FD)
7102 fd = openat(dir_fd, path.narrow, flags, mode);
7103 else
7104#endif
7105 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007106 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007107
Larry Hastings9cf065c2012-06-22 16:30:09 -07007108 if (fd == -1) {
7109#ifdef MS_WINDOWS
7110 /* force use of posix_error here for exact backwards compatibility */
7111 if (path.wide)
7112 return_value = posix_error();
7113 else
7114#endif
7115 return_value = path_error("open", &path);
7116 goto exit;
7117 }
7118
7119 return_value = PyLong_FromLong((long)fd);
7120
7121exit:
7122 path_cleanup(&path);
7123 return return_value;
7124}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007125
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007126PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007127"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007128Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007129
Barry Warsaw53699e91996-12-10 23:23:01 +00007130static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007131posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007132{
Victor Stinner8c62be82010-05-06 00:08:46 +00007133 int fd, res;
7134 if (!PyArg_ParseTuple(args, "i:close", &fd))
7135 return NULL;
7136 if (!_PyVerify_fd(fd))
7137 return posix_error();
7138 Py_BEGIN_ALLOW_THREADS
7139 res = close(fd);
7140 Py_END_ALLOW_THREADS
7141 if (res < 0)
7142 return posix_error();
7143 Py_INCREF(Py_None);
7144 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007145}
7146
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007147
Victor Stinner8c62be82010-05-06 00:08:46 +00007148PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007149"closerange(fd_low, fd_high)\n\n\
7150Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7151
7152static PyObject *
7153posix_closerange(PyObject *self, PyObject *args)
7154{
Victor Stinner8c62be82010-05-06 00:08:46 +00007155 int fd_from, fd_to, i;
7156 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7157 return NULL;
7158 Py_BEGIN_ALLOW_THREADS
7159 for (i = fd_from; i < fd_to; i++)
7160 if (_PyVerify_fd(i))
7161 close(i);
7162 Py_END_ALLOW_THREADS
7163 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007164}
7165
7166
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007167PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007168"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007169Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007170
Barry Warsaw53699e91996-12-10 23:23:01 +00007171static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007172posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007173{
Victor Stinner8c62be82010-05-06 00:08:46 +00007174 int fd;
7175 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7176 return NULL;
7177 if (!_PyVerify_fd(fd))
7178 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007179 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007180 if (fd < 0)
7181 return posix_error();
7182 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007183}
7184
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007185
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007186PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007187"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007188Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007189
Barry Warsaw53699e91996-12-10 23:23:01 +00007190static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007191posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007192{
Victor Stinner8c62be82010-05-06 00:08:46 +00007193 int fd, fd2, res;
7194 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
7195 return NULL;
7196 if (!_PyVerify_fd_dup2(fd, fd2))
7197 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007198 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00007199 if (res < 0)
7200 return posix_error();
7201 Py_INCREF(Py_None);
7202 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007203}
7204
Ross Lagerwall7807c352011-03-17 20:20:30 +02007205#ifdef HAVE_LOCKF
7206PyDoc_STRVAR(posix_lockf__doc__,
7207"lockf(fd, cmd, len)\n\n\
7208Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7209fd is an open file descriptor.\n\
7210cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7211F_TEST.\n\
7212len specifies the section of the file to lock.");
7213
7214static PyObject *
7215posix_lockf(PyObject *self, PyObject *args)
7216{
7217 int fd, cmd, res;
7218 off_t len;
7219 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7220 &fd, &cmd, _parse_off_t, &len))
7221 return NULL;
7222
7223 Py_BEGIN_ALLOW_THREADS
7224 res = lockf(fd, cmd, len);
7225 Py_END_ALLOW_THREADS
7226
7227 if (res < 0)
7228 return posix_error();
7229
7230 Py_RETURN_NONE;
7231}
7232#endif
7233
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007234
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007235PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007236"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007237Set the current position of a file descriptor.\n\
7238Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007239
Barry Warsaw53699e91996-12-10 23:23:01 +00007240static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007241posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007242{
Victor Stinner8c62be82010-05-06 00:08:46 +00007243 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007244#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007245 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007246#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007247 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007248#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007249 PyObject *posobj;
7250 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007251 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007252#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007253 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7254 switch (how) {
7255 case 0: how = SEEK_SET; break;
7256 case 1: how = SEEK_CUR; break;
7257 case 2: how = SEEK_END; break;
7258 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007259#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007260
Ross Lagerwall8e749672011-03-17 21:54:07 +02007261#if !defined(HAVE_LARGEFILE_SUPPORT)
7262 pos = PyLong_AsLong(posobj);
7263#else
7264 pos = PyLong_AsLongLong(posobj);
7265#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007266 if (PyErr_Occurred())
7267 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007268
Victor Stinner8c62be82010-05-06 00:08:46 +00007269 if (!_PyVerify_fd(fd))
7270 return posix_error();
7271 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007272#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007273 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007274#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007275 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007276#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007277 Py_END_ALLOW_THREADS
7278 if (res < 0)
7279 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007280
7281#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007282 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007283#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007284 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007285#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007286}
7287
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007288
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007289PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007290"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007291Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007292
Barry Warsaw53699e91996-12-10 23:23:01 +00007293static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007294posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007295{
Victor Stinner8c62be82010-05-06 00:08:46 +00007296 int fd, size;
7297 Py_ssize_t n;
7298 PyObject *buffer;
7299 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7300 return NULL;
7301 if (size < 0) {
7302 errno = EINVAL;
7303 return posix_error();
7304 }
7305 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7306 if (buffer == NULL)
7307 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007308 if (!_PyVerify_fd(fd)) {
7309 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007310 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007311 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007312 Py_BEGIN_ALLOW_THREADS
7313 n = read(fd, PyBytes_AS_STRING(buffer), size);
7314 Py_END_ALLOW_THREADS
7315 if (n < 0) {
7316 Py_DECREF(buffer);
7317 return posix_error();
7318 }
7319 if (n != size)
7320 _PyBytes_Resize(&buffer, n);
7321 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007322}
7323
Ross Lagerwall7807c352011-03-17 20:20:30 +02007324#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7325 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007326static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007327iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7328{
7329 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007330 Py_ssize_t blen, total = 0;
7331
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007332 *iov = PyMem_New(struct iovec, cnt);
7333 if (*iov == NULL) {
7334 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007335 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007336 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007337
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007338 *buf = PyMem_New(Py_buffer, cnt);
7339 if (*buf == NULL) {
7340 PyMem_Del(*iov);
7341 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007342 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007343 }
7344
7345 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007346 PyObject *item = PySequence_GetItem(seq, i);
7347 if (item == NULL)
7348 goto fail;
7349 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7350 Py_DECREF(item);
7351 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007352 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007353 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007354 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007355 blen = (*buf)[i].len;
7356 (*iov)[i].iov_len = blen;
7357 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007358 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007359 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007360
7361fail:
7362 PyMem_Del(*iov);
7363 for (j = 0; j < i; j++) {
7364 PyBuffer_Release(&(*buf)[j]);
7365 }
7366 PyMem_Del(*buf);
7367 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007368}
7369
7370static void
7371iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7372{
7373 int i;
7374 PyMem_Del(iov);
7375 for (i = 0; i < cnt; i++) {
7376 PyBuffer_Release(&buf[i]);
7377 }
7378 PyMem_Del(buf);
7379}
7380#endif
7381
Ross Lagerwall7807c352011-03-17 20:20:30 +02007382#ifdef HAVE_READV
7383PyDoc_STRVAR(posix_readv__doc__,
7384"readv(fd, buffers) -> bytesread\n\n\
7385Read from a file descriptor into a number of writable buffers. buffers\n\
7386is an arbitrary sequence of writable buffers.\n\
7387Returns the total number of bytes read.");
7388
7389static PyObject *
7390posix_readv(PyObject *self, PyObject *args)
7391{
7392 int fd, cnt;
7393 Py_ssize_t n;
7394 PyObject *seq;
7395 struct iovec *iov;
7396 Py_buffer *buf;
7397
7398 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7399 return NULL;
7400 if (!PySequence_Check(seq)) {
7401 PyErr_SetString(PyExc_TypeError,
7402 "readv() arg 2 must be a sequence");
7403 return NULL;
7404 }
7405 cnt = PySequence_Size(seq);
7406
7407 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7408 return NULL;
7409
7410 Py_BEGIN_ALLOW_THREADS
7411 n = readv(fd, iov, cnt);
7412 Py_END_ALLOW_THREADS
7413
7414 iov_cleanup(iov, buf, cnt);
7415 return PyLong_FromSsize_t(n);
7416}
7417#endif
7418
7419#ifdef HAVE_PREAD
7420PyDoc_STRVAR(posix_pread__doc__,
7421"pread(fd, buffersize, offset) -> string\n\n\
7422Read from a file descriptor, fd, at a position of offset. It will read up\n\
7423to buffersize number of bytes. The file offset remains unchanged.");
7424
7425static PyObject *
7426posix_pread(PyObject *self, PyObject *args)
7427{
7428 int fd, size;
7429 off_t offset;
7430 Py_ssize_t n;
7431 PyObject *buffer;
7432 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7433 return NULL;
7434
7435 if (size < 0) {
7436 errno = EINVAL;
7437 return posix_error();
7438 }
7439 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7440 if (buffer == NULL)
7441 return NULL;
7442 if (!_PyVerify_fd(fd)) {
7443 Py_DECREF(buffer);
7444 return posix_error();
7445 }
7446 Py_BEGIN_ALLOW_THREADS
7447 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7448 Py_END_ALLOW_THREADS
7449 if (n < 0) {
7450 Py_DECREF(buffer);
7451 return posix_error();
7452 }
7453 if (n != size)
7454 _PyBytes_Resize(&buffer, n);
7455 return buffer;
7456}
7457#endif
7458
7459PyDoc_STRVAR(posix_write__doc__,
7460"write(fd, string) -> byteswritten\n\n\
7461Write a string to a file descriptor.");
7462
7463static PyObject *
7464posix_write(PyObject *self, PyObject *args)
7465{
7466 Py_buffer pbuf;
7467 int fd;
7468 Py_ssize_t size, len;
7469
7470 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
7471 return NULL;
7472 if (!_PyVerify_fd(fd)) {
7473 PyBuffer_Release(&pbuf);
7474 return posix_error();
7475 }
7476 len = pbuf.len;
7477 Py_BEGIN_ALLOW_THREADS
7478#if defined(MS_WIN64) || defined(MS_WINDOWS)
7479 if (len > INT_MAX)
7480 len = INT_MAX;
7481 size = write(fd, pbuf.buf, (int)len);
7482#else
7483 size = write(fd, pbuf.buf, len);
7484#endif
7485 Py_END_ALLOW_THREADS
7486 PyBuffer_Release(&pbuf);
7487 if (size < 0)
7488 return posix_error();
7489 return PyLong_FromSsize_t(size);
7490}
7491
7492#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007493PyDoc_STRVAR(posix_sendfile__doc__,
7494"sendfile(out, in, offset, nbytes) -> byteswritten\n\
7495sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
7496 -> byteswritten\n\
7497Copy nbytes bytes from file descriptor in to file descriptor out.");
7498
7499static PyObject *
7500posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
7501{
7502 int in, out;
7503 Py_ssize_t ret;
7504 off_t offset;
7505
7506#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
7507#ifndef __APPLE__
7508 Py_ssize_t len;
7509#endif
7510 PyObject *headers = NULL, *trailers = NULL;
7511 Py_buffer *hbuf, *tbuf;
7512 off_t sbytes;
7513 struct sf_hdtr sf;
7514 int flags = 0;
7515 sf.headers = NULL;
7516 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00007517 static char *keywords[] = {"out", "in",
7518 "offset", "count",
7519 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007520
7521#ifdef __APPLE__
7522 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007523 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007524#else
7525 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007526 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007527#endif
7528 &headers, &trailers, &flags))
7529 return NULL;
7530 if (headers != NULL) {
7531 if (!PySequence_Check(headers)) {
7532 PyErr_SetString(PyExc_TypeError,
7533 "sendfile() headers must be a sequence or None");
7534 return NULL;
7535 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007536 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007537 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007538 if (sf.hdr_cnt > 0 &&
7539 !(i = iov_setup(&(sf.headers), &hbuf,
7540 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007541 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007542#ifdef __APPLE__
7543 sbytes += i;
7544#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007545 }
7546 }
7547 if (trailers != NULL) {
7548 if (!PySequence_Check(trailers)) {
7549 PyErr_SetString(PyExc_TypeError,
7550 "sendfile() trailers must be a sequence or None");
7551 return NULL;
7552 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007553 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007554 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007555 if (sf.trl_cnt > 0 &&
7556 !(i = iov_setup(&(sf.trailers), &tbuf,
7557 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007558 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007559#ifdef __APPLE__
7560 sbytes += i;
7561#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007562 }
7563 }
7564
7565 Py_BEGIN_ALLOW_THREADS
7566#ifdef __APPLE__
7567 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
7568#else
7569 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
7570#endif
7571 Py_END_ALLOW_THREADS
7572
7573 if (sf.headers != NULL)
7574 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
7575 if (sf.trailers != NULL)
7576 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
7577
7578 if (ret < 0) {
7579 if ((errno == EAGAIN) || (errno == EBUSY)) {
7580 if (sbytes != 0) {
7581 // some data has been sent
7582 goto done;
7583 }
7584 else {
7585 // no data has been sent; upper application is supposed
7586 // to retry on EAGAIN or EBUSY
7587 return posix_error();
7588 }
7589 }
7590 return posix_error();
7591 }
7592 goto done;
7593
7594done:
7595 #if !defined(HAVE_LARGEFILE_SUPPORT)
7596 return Py_BuildValue("l", sbytes);
7597 #else
7598 return Py_BuildValue("L", sbytes);
7599 #endif
7600
7601#else
7602 Py_ssize_t count;
7603 PyObject *offobj;
7604 static char *keywords[] = {"out", "in",
7605 "offset", "count", NULL};
7606 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
7607 keywords, &out, &in, &offobj, &count))
7608 return NULL;
7609#ifdef linux
7610 if (offobj == Py_None) {
7611 Py_BEGIN_ALLOW_THREADS
7612 ret = sendfile(out, in, NULL, count);
7613 Py_END_ALLOW_THREADS
7614 if (ret < 0)
7615 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02007616 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007617 }
7618#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00007619 if (!_parse_off_t(offobj, &offset))
7620 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007621 Py_BEGIN_ALLOW_THREADS
7622 ret = sendfile(out, in, &offset, count);
7623 Py_END_ALLOW_THREADS
7624 if (ret < 0)
7625 return posix_error();
7626 return Py_BuildValue("n", ret);
7627#endif
7628}
7629#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007630
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007631PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007632"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07007633Like stat(), but for an open file descriptor.\n\
7634Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007635
Barry Warsaw53699e91996-12-10 23:23:01 +00007636static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007637posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007638{
Victor Stinner8c62be82010-05-06 00:08:46 +00007639 int fd;
7640 STRUCT_STAT st;
7641 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01007642 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007643 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007644#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00007645 /* on OpenVMS we must ensure that all bytes are written to the file */
7646 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007647#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007648 Py_BEGIN_ALLOW_THREADS
7649 res = FSTAT(fd, &st);
7650 Py_END_ALLOW_THREADS
7651 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00007652#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007653 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00007654#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007655 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00007656#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007657 }
Tim Peters5aa91602002-01-30 05:46:57 +00007658
Victor Stinner4195b5c2012-02-08 23:03:19 +01007659 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00007660}
7661
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007662PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007663"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007664Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007665connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00007666
7667static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00007668posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00007669{
Victor Stinner8c62be82010-05-06 00:08:46 +00007670 int fd;
7671 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
7672 return NULL;
7673 if (!_PyVerify_fd(fd))
7674 return PyBool_FromLong(0);
7675 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00007676}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007677
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007678#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007679PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007680"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007681Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007682
Barry Warsaw53699e91996-12-10 23:23:01 +00007683static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007684posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007685{
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007686#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007687 int fds[2];
7688 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007689 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00007690 if (res != 0)
7691 return posix_error();
7692 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007693#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007694 HANDLE read, write;
7695 int read_fd, write_fd;
7696 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00007697 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00007698 if (!ok)
7699 return win32_error("CreatePipe", NULL);
7700 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
7701 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
7702 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007703#endif /* MS_WINDOWS */
Guido van Rossum687dd131993-05-17 08:34:16 +00007704}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007705#endif /* HAVE_PIPE */
7706
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007707#ifdef HAVE_PIPE2
7708PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02007709"pipe2(flags) -> (read_end, write_end)\n\n\
7710Create a pipe with flags set atomically.\n\
7711flags can be constructed by ORing together one or more of these values:\n\
7712O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007713");
7714
7715static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02007716posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007717{
Charles-François Natali368f34b2011-06-06 19:49:47 +02007718 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007719 int fds[2];
7720 int res;
7721
Charles-François Natali368f34b2011-06-06 19:49:47 +02007722 flags = PyLong_AsLong(arg);
7723 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007724 return NULL;
7725
7726 res = pipe2(fds, flags);
7727 if (res != 0)
7728 return posix_error();
7729 return Py_BuildValue("(ii)", fds[0], fds[1]);
7730}
7731#endif /* HAVE_PIPE2 */
7732
Ross Lagerwall7807c352011-03-17 20:20:30 +02007733#ifdef HAVE_WRITEV
7734PyDoc_STRVAR(posix_writev__doc__,
7735"writev(fd, buffers) -> byteswritten\n\n\
7736Write the contents of buffers to a file descriptor, where buffers is an\n\
7737arbitrary sequence of buffers.\n\
7738Returns the total bytes written.");
7739
7740static PyObject *
7741posix_writev(PyObject *self, PyObject *args)
7742{
7743 int fd, cnt;
7744 Py_ssize_t res;
7745 PyObject *seq;
7746 struct iovec *iov;
7747 Py_buffer *buf;
7748 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
7749 return NULL;
7750 if (!PySequence_Check(seq)) {
7751 PyErr_SetString(PyExc_TypeError,
7752 "writev() arg 2 must be a sequence");
7753 return NULL;
7754 }
7755 cnt = PySequence_Size(seq);
7756
7757 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
7758 return NULL;
7759 }
7760
7761 Py_BEGIN_ALLOW_THREADS
7762 res = writev(fd, iov, cnt);
7763 Py_END_ALLOW_THREADS
7764
7765 iov_cleanup(iov, buf, cnt);
7766 return PyLong_FromSsize_t(res);
7767}
7768#endif
7769
7770#ifdef HAVE_PWRITE
7771PyDoc_STRVAR(posix_pwrite__doc__,
7772"pwrite(fd, string, offset) -> byteswritten\n\n\
7773Write string to a file descriptor, fd, from offset, leaving the file\n\
7774offset unchanged.");
7775
7776static PyObject *
7777posix_pwrite(PyObject *self, PyObject *args)
7778{
7779 Py_buffer pbuf;
7780 int fd;
7781 off_t offset;
7782 Py_ssize_t size;
7783
7784 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
7785 return NULL;
7786
7787 if (!_PyVerify_fd(fd)) {
7788 PyBuffer_Release(&pbuf);
7789 return posix_error();
7790 }
7791 Py_BEGIN_ALLOW_THREADS
7792 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
7793 Py_END_ALLOW_THREADS
7794 PyBuffer_Release(&pbuf);
7795 if (size < 0)
7796 return posix_error();
7797 return PyLong_FromSsize_t(size);
7798}
7799#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007800
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007801#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007802PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007803"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
7804Create a FIFO (a POSIX named pipe).\n\
7805\n\
7806If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7807 and path should be relative; path will then be relative to that directory.\n\
7808dir_fd may not be implemented on your platform.\n\
7809 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007810
Barry Warsaw53699e91996-12-10 23:23:01 +00007811static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007812posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007813{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007814 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00007815 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007816 int dir_fd = DEFAULT_DIR_FD;
7817 int result;
7818 PyObject *return_value = NULL;
7819 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
7820
7821 memset(&path, 0, sizeof(path));
7822 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
7823 path_converter, &path,
7824 &mode,
7825#ifdef HAVE_MKFIFOAT
7826 dir_fd_converter, &dir_fd
7827#else
7828 dir_fd_unavailable, &dir_fd
7829#endif
7830 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007831 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007832
Victor Stinner8c62be82010-05-06 00:08:46 +00007833 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007834#ifdef HAVE_MKFIFOAT
7835 if (dir_fd != DEFAULT_DIR_FD)
7836 result = mkfifoat(dir_fd, path.narrow, mode);
7837 else
7838#endif
7839 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007840 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007841
7842 if (result < 0) {
7843 return_value = posix_error();
7844 goto exit;
7845 }
7846
7847 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00007848 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007849
7850exit:
7851 path_cleanup(&path);
7852 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007853}
7854#endif
7855
Neal Norwitz11690112002-07-30 01:08:28 +00007856#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007857PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007858"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007859Create a filesystem node (file, device special file or named pipe)\n\
7860named filename. mode specifies both the permissions to use and the\n\
7861type of node to be created, being combined (bitwise OR) with one of\n\
7862S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007863device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07007864os.makedev()), otherwise it is ignored.\n\
7865\n\
7866If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7867 and path should be relative; path will then be relative to that directory.\n\
7868dir_fd may not be implemented on your platform.\n\
7869 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007870
7871
7872static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007873posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007874{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007875 path_t path;
7876 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00007877 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007878 int dir_fd = DEFAULT_DIR_FD;
7879 int result;
7880 PyObject *return_value = NULL;
7881 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
7882
7883 memset(&path, 0, sizeof(path));
7884 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
7885 path_converter, &path,
7886 &mode, &device,
7887#ifdef HAVE_MKNODAT
7888 dir_fd_converter, &dir_fd
7889#else
7890 dir_fd_unavailable, &dir_fd
7891#endif
7892 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007893 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007894
Victor Stinner8c62be82010-05-06 00:08:46 +00007895 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007896#ifdef HAVE_MKNODAT
7897 if (dir_fd != DEFAULT_DIR_FD)
7898 result = mknodat(dir_fd, path.narrow, mode, device);
7899 else
7900#endif
7901 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00007902 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007903
7904 if (result < 0) {
7905 return_value = posix_error();
7906 goto exit;
7907 }
7908
7909 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00007910 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02007911
Larry Hastings9cf065c2012-06-22 16:30:09 -07007912exit:
7913 path_cleanup(&path);
7914 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007915}
7916#endif
7917
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007918#ifdef HAVE_DEVICE_MACROS
7919PyDoc_STRVAR(posix_major__doc__,
7920"major(device) -> major number\n\
7921Extracts a device major number from a raw device number.");
7922
7923static PyObject *
7924posix_major(PyObject *self, PyObject *args)
7925{
Victor Stinner8c62be82010-05-06 00:08:46 +00007926 int device;
7927 if (!PyArg_ParseTuple(args, "i:major", &device))
7928 return NULL;
7929 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007930}
7931
7932PyDoc_STRVAR(posix_minor__doc__,
7933"minor(device) -> minor number\n\
7934Extracts a device minor number from a raw device number.");
7935
7936static PyObject *
7937posix_minor(PyObject *self, PyObject *args)
7938{
Victor Stinner8c62be82010-05-06 00:08:46 +00007939 int device;
7940 if (!PyArg_ParseTuple(args, "i:minor", &device))
7941 return NULL;
7942 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007943}
7944
7945PyDoc_STRVAR(posix_makedev__doc__,
7946"makedev(major, minor) -> device number\n\
7947Composes a raw device number from the major and minor device numbers.");
7948
7949static PyObject *
7950posix_makedev(PyObject *self, PyObject *args)
7951{
Victor Stinner8c62be82010-05-06 00:08:46 +00007952 int major, minor;
7953 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
7954 return NULL;
7955 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007956}
7957#endif /* device macros */
7958
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007959
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007960#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007961PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007962"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007963Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007964
Barry Warsaw53699e91996-12-10 23:23:01 +00007965static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007966posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007967{
Victor Stinner8c62be82010-05-06 00:08:46 +00007968 int fd;
7969 off_t length;
7970 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007971
Ross Lagerwall7807c352011-03-17 20:20:30 +02007972 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00007973 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007974
Victor Stinner8c62be82010-05-06 00:08:46 +00007975 Py_BEGIN_ALLOW_THREADS
7976 res = ftruncate(fd, length);
7977 Py_END_ALLOW_THREADS
7978 if (res < 0)
7979 return posix_error();
7980 Py_INCREF(Py_None);
7981 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007982}
7983#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007984
Ross Lagerwall7807c352011-03-17 20:20:30 +02007985#ifdef HAVE_TRUNCATE
7986PyDoc_STRVAR(posix_truncate__doc__,
7987"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02007988Truncate the file given by path to length bytes.\n\
7989On some platforms, path may also be specified as an open file descriptor.\n\
7990 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02007991
7992static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02007993posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02007994{
Georg Brandl306336b2012-06-24 12:55:33 +02007995 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007996 off_t length;
7997 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02007998 PyObject *result = NULL;
7999 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008000
Georg Brandl306336b2012-06-24 12:55:33 +02008001 memset(&path, 0, sizeof(path));
8002#ifdef HAVE_FTRUNCATE
8003 path.allow_fd = 1;
8004#endif
8005 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8006 path_converter, &path,
8007 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008008 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008009
8010 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008011#ifdef HAVE_FTRUNCATE
8012 if (path.fd != -1)
8013 res = ftruncate(path.fd, length);
8014 else
8015#endif
8016 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008017 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008018 if (res < 0)
Georg Brandl306336b2012-06-24 12:55:33 +02008019 result = path_posix_error("truncate", &path);
8020 else {
8021 Py_INCREF(Py_None);
8022 result = Py_None;
8023 }
8024 path_cleanup(&path);
8025 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008026}
8027#endif
8028
8029#ifdef HAVE_POSIX_FALLOCATE
8030PyDoc_STRVAR(posix_posix_fallocate__doc__,
8031"posix_fallocate(fd, offset, len)\n\n\
8032Ensures that enough disk space is allocated for the file specified by fd\n\
8033starting from offset and continuing for len bytes.");
8034
8035static PyObject *
8036posix_posix_fallocate(PyObject *self, PyObject *args)
8037{
8038 off_t len, offset;
8039 int res, fd;
8040
8041 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8042 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8043 return NULL;
8044
8045 Py_BEGIN_ALLOW_THREADS
8046 res = posix_fallocate(fd, offset, len);
8047 Py_END_ALLOW_THREADS
8048 if (res != 0) {
8049 errno = res;
8050 return posix_error();
8051 }
8052 Py_RETURN_NONE;
8053}
8054#endif
8055
8056#ifdef HAVE_POSIX_FADVISE
8057PyDoc_STRVAR(posix_posix_fadvise__doc__,
8058"posix_fadvise(fd, offset, len, advice)\n\n\
8059Announces an intention to access data in a specific pattern thus allowing\n\
8060the kernel to make optimizations.\n\
8061The advice applies to the region of the file specified by fd starting at\n\
8062offset and continuing for len bytes.\n\
8063advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8064POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8065POSIX_FADV_DONTNEED.");
8066
8067static PyObject *
8068posix_posix_fadvise(PyObject *self, PyObject *args)
8069{
8070 off_t len, offset;
8071 int res, fd, advice;
8072
8073 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8074 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8075 return NULL;
8076
8077 Py_BEGIN_ALLOW_THREADS
8078 res = posix_fadvise(fd, offset, len, advice);
8079 Py_END_ALLOW_THREADS
8080 if (res != 0) {
8081 errno = res;
8082 return posix_error();
8083 }
8084 Py_RETURN_NONE;
8085}
8086#endif
8087
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008088#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008089PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008090"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008091Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008092
Fred Drake762e2061999-08-26 17:23:54 +00008093/* Save putenv() parameters as values here, so we can collect them when they
8094 * get re-set with another call for the same key. */
8095static PyObject *posix_putenv_garbage;
8096
Tim Peters5aa91602002-01-30 05:46:57 +00008097static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008098posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008099{
Victor Stinner84ae1182010-05-06 22:05:07 +00008100 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008101#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008102 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008103 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008104
Victor Stinner8c62be82010-05-06 00:08:46 +00008105 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008106 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008107 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008108 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008109
Victor Stinner65170952011-11-22 22:16:17 +01008110 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008111 if (newstr == NULL) {
8112 PyErr_NoMemory();
8113 goto error;
8114 }
Victor Stinner65170952011-11-22 22:16:17 +01008115 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8116 PyErr_Format(PyExc_ValueError,
8117 "the environment variable is longer than %u characters",
8118 _MAX_ENV);
8119 goto error;
8120 }
8121
Victor Stinner8c62be82010-05-06 00:08:46 +00008122 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008123 if (newenv == NULL)
8124 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008125 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008126 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008127 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008128 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008129#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008130 PyObject *os1, *os2;
8131 char *s1, *s2;
8132 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008133
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008134 if (!PyArg_ParseTuple(args,
8135 "O&O&:putenv",
8136 PyUnicode_FSConverter, &os1,
8137 PyUnicode_FSConverter, &os2))
8138 return NULL;
8139 s1 = PyBytes_AsString(os1);
8140 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008141
Victor Stinner65170952011-11-22 22:16:17 +01008142 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008143 if (newstr == NULL) {
8144 PyErr_NoMemory();
8145 goto error;
8146 }
8147
Victor Stinner8c62be82010-05-06 00:08:46 +00008148 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008149 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008150 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008151 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008152 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008153#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008154
Victor Stinner8c62be82010-05-06 00:08:46 +00008155 /* Install the first arg and newstr in posix_putenv_garbage;
8156 * this will cause previous value to be collected. This has to
8157 * happen after the real putenv() call because the old value
8158 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008159 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008160 /* really not much we can do; just leak */
8161 PyErr_Clear();
8162 }
8163 else {
8164 Py_DECREF(newstr);
8165 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008166
Martin v. Löwis011e8422009-05-05 04:43:17 +00008167#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008168 Py_DECREF(os1);
8169 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008170#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008171 Py_RETURN_NONE;
8172
8173error:
8174#ifndef MS_WINDOWS
8175 Py_DECREF(os1);
8176 Py_DECREF(os2);
8177#endif
8178 Py_XDECREF(newstr);
8179 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008180}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008181#endif /* putenv */
8182
Guido van Rossumc524d952001-10-19 01:31:59 +00008183#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008184PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008185"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008186Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008187
8188static PyObject *
8189posix_unsetenv(PyObject *self, PyObject *args)
8190{
Victor Stinner65170952011-11-22 22:16:17 +01008191 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008192#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008193 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008194#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008195
8196 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008197
Victor Stinner65170952011-11-22 22:16:17 +01008198 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008199 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008200
Victor Stinner984890f2011-11-24 13:53:38 +01008201#ifdef HAVE_BROKEN_UNSETENV
8202 unsetenv(PyBytes_AS_STRING(name));
8203#else
Victor Stinner65170952011-11-22 22:16:17 +01008204 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008205 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008206 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008207 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008208 }
Victor Stinner984890f2011-11-24 13:53:38 +01008209#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008210
Victor Stinner8c62be82010-05-06 00:08:46 +00008211 /* Remove the key from posix_putenv_garbage;
8212 * this will cause it to be collected. This has to
8213 * happen after the real unsetenv() call because the
8214 * old value was still accessible until then.
8215 */
Victor Stinner65170952011-11-22 22:16:17 +01008216 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008217 /* really not much we can do; just leak */
8218 PyErr_Clear();
8219 }
Victor Stinner65170952011-11-22 22:16:17 +01008220 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008221 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008222}
8223#endif /* unsetenv */
8224
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008225PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008226"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008227Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008228
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008229static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008230posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008231{
Victor Stinner8c62be82010-05-06 00:08:46 +00008232 int code;
8233 char *message;
8234 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8235 return NULL;
8236 message = strerror(code);
8237 if (message == NULL) {
8238 PyErr_SetString(PyExc_ValueError,
8239 "strerror() argument out of range");
8240 return NULL;
8241 }
Victor Stinner1b579672011-12-17 05:47:23 +01008242 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008243}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008244
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008245
Guido van Rossumc9641791998-08-04 15:26:23 +00008246#ifdef HAVE_SYS_WAIT_H
8247
Fred Drake106c1a02002-04-23 15:58:02 +00008248#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008249PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008250"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008251Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008252
8253static PyObject *
8254posix_WCOREDUMP(PyObject *self, PyObject *args)
8255{
Victor Stinner8c62be82010-05-06 00:08:46 +00008256 WAIT_TYPE status;
8257 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008258
Victor Stinner8c62be82010-05-06 00:08:46 +00008259 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8260 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008261
Victor Stinner8c62be82010-05-06 00:08:46 +00008262 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008263}
8264#endif /* WCOREDUMP */
8265
8266#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008267PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008268"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008269Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008270job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00008271
8272static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008273posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00008274{
Victor Stinner8c62be82010-05-06 00:08:46 +00008275 WAIT_TYPE status;
8276 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008277
Victor Stinner8c62be82010-05-06 00:08:46 +00008278 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
8279 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008280
Victor Stinner8c62be82010-05-06 00:08:46 +00008281 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008282}
8283#endif /* WIFCONTINUED */
8284
Guido van Rossumc9641791998-08-04 15:26:23 +00008285#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008286PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008287"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008288Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008289
8290static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008291posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008292{
Victor Stinner8c62be82010-05-06 00:08:46 +00008293 WAIT_TYPE status;
8294 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008295
Victor Stinner8c62be82010-05-06 00:08:46 +00008296 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
8297 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008298
Victor Stinner8c62be82010-05-06 00:08:46 +00008299 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008300}
8301#endif /* WIFSTOPPED */
8302
8303#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008304PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008305"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008306Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008307
8308static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008309posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008310{
Victor Stinner8c62be82010-05-06 00:08:46 +00008311 WAIT_TYPE status;
8312 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008313
Victor Stinner8c62be82010-05-06 00:08:46 +00008314 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8315 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008316
Victor Stinner8c62be82010-05-06 00:08:46 +00008317 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008318}
8319#endif /* WIFSIGNALED */
8320
8321#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008322PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008323"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008324Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008325system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008326
8327static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008328posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008329{
Victor Stinner8c62be82010-05-06 00:08:46 +00008330 WAIT_TYPE status;
8331 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008332
Victor Stinner8c62be82010-05-06 00:08:46 +00008333 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
8334 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008335
Victor Stinner8c62be82010-05-06 00:08:46 +00008336 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008337}
8338#endif /* WIFEXITED */
8339
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008340#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008341PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008342"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008343Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008344
8345static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008346posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008347{
Victor Stinner8c62be82010-05-06 00:08:46 +00008348 WAIT_TYPE status;
8349 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008350
Victor Stinner8c62be82010-05-06 00:08:46 +00008351 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8352 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008353
Victor Stinner8c62be82010-05-06 00:08:46 +00008354 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008355}
8356#endif /* WEXITSTATUS */
8357
8358#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008359PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008360"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008361Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008362value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008363
8364static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008365posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008366{
Victor Stinner8c62be82010-05-06 00:08:46 +00008367 WAIT_TYPE status;
8368 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008369
Victor Stinner8c62be82010-05-06 00:08:46 +00008370 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8371 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008372
Victor Stinner8c62be82010-05-06 00:08:46 +00008373 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008374}
8375#endif /* WTERMSIG */
8376
8377#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008378PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008379"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008380Return the signal that stopped the process that provided\n\
8381the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008382
8383static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008384posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008385{
Victor Stinner8c62be82010-05-06 00:08:46 +00008386 WAIT_TYPE status;
8387 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008388
Victor Stinner8c62be82010-05-06 00:08:46 +00008389 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8390 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008391
Victor Stinner8c62be82010-05-06 00:08:46 +00008392 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008393}
8394#endif /* WSTOPSIG */
8395
8396#endif /* HAVE_SYS_WAIT_H */
8397
8398
Thomas Wouters477c8d52006-05-27 19:21:47 +00008399#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00008400#ifdef _SCO_DS
8401/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
8402 needed definitions in sys/statvfs.h */
8403#define _SVID3
8404#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008405#include <sys/statvfs.h>
8406
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008407static PyObject*
8408_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008409 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8410 if (v == NULL)
8411 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008412
8413#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008414 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8415 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8416 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8417 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8418 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8419 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8420 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8421 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8422 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8423 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008424#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008425 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8426 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8427 PyStructSequence_SET_ITEM(v, 2,
8428 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8429 PyStructSequence_SET_ITEM(v, 3,
8430 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8431 PyStructSequence_SET_ITEM(v, 4,
8432 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8433 PyStructSequence_SET_ITEM(v, 5,
8434 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8435 PyStructSequence_SET_ITEM(v, 6,
8436 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8437 PyStructSequence_SET_ITEM(v, 7,
8438 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
8439 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8440 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008441#endif
8442
Victor Stinner8c62be82010-05-06 00:08:46 +00008443 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008444}
8445
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008446PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008447"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008448Perform an fstatvfs system call on the given fd.\n\
8449Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008450
8451static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008452posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008453{
Victor Stinner8c62be82010-05-06 00:08:46 +00008454 int fd, res;
8455 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008456
Victor Stinner8c62be82010-05-06 00:08:46 +00008457 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
8458 return NULL;
8459 Py_BEGIN_ALLOW_THREADS
8460 res = fstatvfs(fd, &st);
8461 Py_END_ALLOW_THREADS
8462 if (res != 0)
8463 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008464
Victor Stinner8c62be82010-05-06 00:08:46 +00008465 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008466}
Thomas Wouters477c8d52006-05-27 19:21:47 +00008467#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008468
8469
Thomas Wouters477c8d52006-05-27 19:21:47 +00008470#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008471#include <sys/statvfs.h>
8472
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008473PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008474"statvfs(path)\n\n\
8475Perform a statvfs system call on the given path.\n\
8476\n\
8477path may always be specified as a string.\n\
8478On some platforms, path may also be specified as an open file descriptor.\n\
8479 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008480
8481static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008482posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008483{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008484 static char *keywords[] = {"path", NULL};
8485 path_t path;
8486 int result;
8487 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008488 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008489
Larry Hastings9cf065c2012-06-22 16:30:09 -07008490 memset(&path, 0, sizeof(path));
8491#ifdef HAVE_FSTATVFS
8492 path.allow_fd = 1;
8493#endif
8494 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
8495 path_converter, &path
8496 ))
8497 return NULL;
8498
8499 Py_BEGIN_ALLOW_THREADS
8500#ifdef HAVE_FSTATVFS
8501 if (path.fd != -1) {
8502#ifdef __APPLE__
8503 /* handle weak-linking on Mac OS X 10.3 */
8504 if (fstatvfs == NULL) {
8505 fd_specified("statvfs", path.fd);
8506 goto exit;
8507 }
8508#endif
8509 result = fstatvfs(path.fd, &st);
8510 }
8511 else
8512#endif
8513 result = statvfs(path.narrow, &st);
8514 Py_END_ALLOW_THREADS
8515
8516 if (result) {
8517 return_value = path_posix_error("statvfs", &path);
8518 goto exit;
8519 }
8520
8521 return_value = _pystatvfs_fromstructstatvfs(st);
8522
8523exit:
8524 path_cleanup(&path);
8525 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00008526}
8527#endif /* HAVE_STATVFS */
8528
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008529#ifdef MS_WINDOWS
8530PyDoc_STRVAR(win32__getdiskusage__doc__,
8531"_getdiskusage(path) -> (total, free)\n\n\
8532Return disk usage statistics about the given path as (total, free) tuple.");
8533
8534static PyObject *
8535win32__getdiskusage(PyObject *self, PyObject *args)
8536{
8537 BOOL retval;
8538 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01008539 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008540
Victor Stinner6139c1b2011-11-09 22:14:14 +01008541 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008542 return NULL;
8543
8544 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01008545 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008546 Py_END_ALLOW_THREADS
8547 if (retval == 0)
8548 return PyErr_SetFromWindowsErr(0);
8549
8550 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
8551}
8552#endif
8553
8554
Fred Drakec9680921999-12-13 16:37:25 +00008555/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
8556 * It maps strings representing configuration variable names to
8557 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00008558 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00008559 * rarely-used constants. There are three separate tables that use
8560 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00008561 *
8562 * This code is always included, even if none of the interfaces that
8563 * need it are included. The #if hackery needed to avoid it would be
8564 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00008565 */
8566struct constdef {
8567 char *name;
8568 long value;
8569};
8570
Fred Drake12c6e2d1999-12-14 21:25:03 +00008571static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008572conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00008573 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00008574{
Christian Heimes217cfd12007-12-02 14:31:20 +00008575 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008576 *valuep = PyLong_AS_LONG(arg);
8577 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00008578 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00008579 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00008580 /* look up the value in the table using a binary search */
8581 size_t lo = 0;
8582 size_t mid;
8583 size_t hi = tablesize;
8584 int cmp;
8585 const char *confname;
8586 if (!PyUnicode_Check(arg)) {
8587 PyErr_SetString(PyExc_TypeError,
8588 "configuration names must be strings or integers");
8589 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008590 }
Stefan Krah0e803b32010-11-26 16:16:47 +00008591 confname = _PyUnicode_AsString(arg);
8592 if (confname == NULL)
8593 return 0;
8594 while (lo < hi) {
8595 mid = (lo + hi) / 2;
8596 cmp = strcmp(confname, table[mid].name);
8597 if (cmp < 0)
8598 hi = mid;
8599 else if (cmp > 0)
8600 lo = mid + 1;
8601 else {
8602 *valuep = table[mid].value;
8603 return 1;
8604 }
8605 }
8606 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
8607 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008608 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00008609}
8610
8611
8612#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
8613static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008614#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008615 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008616#endif
8617#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008618 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008619#endif
Fred Drakec9680921999-12-13 16:37:25 +00008620#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008621 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008622#endif
8623#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00008624 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00008625#endif
8626#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00008627 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00008628#endif
8629#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00008630 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00008631#endif
8632#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008633 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008634#endif
8635#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00008636 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00008637#endif
8638#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008639 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00008640#endif
8641#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008642 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008643#endif
8644#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008645 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00008646#endif
8647#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008648 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008649#endif
8650#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008651 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00008652#endif
8653#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008654 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008655#endif
8656#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008657 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00008658#endif
8659#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008660 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008661#endif
8662#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008663 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00008664#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00008665#ifdef _PC_ACL_ENABLED
8666 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
8667#endif
8668#ifdef _PC_MIN_HOLE_SIZE
8669 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
8670#endif
8671#ifdef _PC_ALLOC_SIZE_MIN
8672 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
8673#endif
8674#ifdef _PC_REC_INCR_XFER_SIZE
8675 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
8676#endif
8677#ifdef _PC_REC_MAX_XFER_SIZE
8678 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
8679#endif
8680#ifdef _PC_REC_MIN_XFER_SIZE
8681 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
8682#endif
8683#ifdef _PC_REC_XFER_ALIGN
8684 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
8685#endif
8686#ifdef _PC_SYMLINK_MAX
8687 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
8688#endif
8689#ifdef _PC_XATTR_ENABLED
8690 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
8691#endif
8692#ifdef _PC_XATTR_EXISTS
8693 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
8694#endif
8695#ifdef _PC_TIMESTAMP_RESOLUTION
8696 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
8697#endif
Fred Drakec9680921999-12-13 16:37:25 +00008698};
8699
Fred Drakec9680921999-12-13 16:37:25 +00008700static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008701conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008702{
8703 return conv_confname(arg, valuep, posix_constants_pathconf,
8704 sizeof(posix_constants_pathconf)
8705 / sizeof(struct constdef));
8706}
8707#endif
8708
8709#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008710PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008711"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008712Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008713If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00008714
8715static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008716posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008717{
8718 PyObject *result = NULL;
8719 int name, fd;
8720
Fred Drake12c6e2d1999-12-14 21:25:03 +00008721 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
8722 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008723 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008724
Stefan Krah0e803b32010-11-26 16:16:47 +00008725 errno = 0;
8726 limit = fpathconf(fd, name);
8727 if (limit == -1 && errno != 0)
8728 posix_error();
8729 else
8730 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008731 }
8732 return result;
8733}
8734#endif
8735
8736
8737#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008738PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008739"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008740Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008741If there is no limit, return -1.\n\
8742On some platforms, path may also be specified as an open file descriptor.\n\
8743 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00008744
8745static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008746posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00008747{
Georg Brandl306336b2012-06-24 12:55:33 +02008748 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00008749 PyObject *result = NULL;
8750 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02008751 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00008752
Georg Brandl306336b2012-06-24 12:55:33 +02008753 memset(&path, 0, sizeof(path));
8754#ifdef HAVE_FPATHCONF
8755 path.allow_fd = 1;
8756#endif
8757 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
8758 path_converter, &path,
8759 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008760 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008761
Victor Stinner8c62be82010-05-06 00:08:46 +00008762 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02008763#ifdef HAVE_FPATHCONF
8764 if (path.fd != -1)
8765 limit = fpathconf(path.fd, name);
8766 else
8767#endif
8768 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00008769 if (limit == -1 && errno != 0) {
8770 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00008771 /* could be a path or name problem */
8772 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00008773 else
Georg Brandl306336b2012-06-24 12:55:33 +02008774 result = path_posix_error("pathconf", &path);
Victor Stinner8c62be82010-05-06 00:08:46 +00008775 }
8776 else
8777 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008778 }
Georg Brandl306336b2012-06-24 12:55:33 +02008779 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00008780 return result;
8781}
8782#endif
8783
8784#ifdef HAVE_CONFSTR
8785static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008786#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00008787 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00008788#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00008789#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008790 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008791#endif
8792#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008793 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008794#endif
Fred Draked86ed291999-12-15 15:34:33 +00008795#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008796 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008797#endif
8798#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008799 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008800#endif
8801#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008802 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008803#endif
8804#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008805 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008806#endif
Fred Drakec9680921999-12-13 16:37:25 +00008807#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008808 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008809#endif
8810#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008811 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008812#endif
8813#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008814 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008815#endif
8816#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008817 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008818#endif
8819#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008820 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008821#endif
8822#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008823 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008824#endif
8825#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008826 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008827#endif
8828#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008829 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008830#endif
Fred Draked86ed291999-12-15 15:34:33 +00008831#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00008832 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00008833#endif
Fred Drakec9680921999-12-13 16:37:25 +00008834#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00008835 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00008836#endif
Fred Draked86ed291999-12-15 15:34:33 +00008837#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008838 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00008839#endif
8840#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008841 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00008842#endif
8843#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008844 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008845#endif
8846#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008847 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00008848#endif
Fred Drakec9680921999-12-13 16:37:25 +00008849#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008850 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008851#endif
8852#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008853 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008854#endif
8855#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008856 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008857#endif
8858#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008859 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008860#endif
8861#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008862 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008863#endif
8864#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008865 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008866#endif
8867#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008868 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008869#endif
8870#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008871 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008872#endif
8873#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008874 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008875#endif
8876#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008877 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008878#endif
8879#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008880 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008881#endif
8882#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008883 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008884#endif
8885#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008886 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008887#endif
8888#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008889 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008890#endif
8891#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008892 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008893#endif
8894#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008895 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008896#endif
Fred Draked86ed291999-12-15 15:34:33 +00008897#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008898 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008899#endif
8900#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008901 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00008902#endif
8903#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00008904 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00008905#endif
8906#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008907 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008908#endif
8909#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008910 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008911#endif
8912#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00008913 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00008914#endif
8915#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008916 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00008917#endif
8918#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00008919 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00008920#endif
8921#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008922 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008923#endif
8924#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008925 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008926#endif
8927#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008928 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008929#endif
8930#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008931 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008932#endif
8933#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00008934 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00008935#endif
Fred Drakec9680921999-12-13 16:37:25 +00008936};
8937
8938static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008939conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008940{
8941 return conv_confname(arg, valuep, posix_constants_confstr,
8942 sizeof(posix_constants_confstr)
8943 / sizeof(struct constdef));
8944}
8945
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008946PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008947"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008948Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008949
8950static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008951posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008952{
8953 PyObject *result = NULL;
8954 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00008955 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00008956 int len;
Fred Drakec9680921999-12-13 16:37:25 +00008957
Victor Stinnercb043522010-09-10 23:49:04 +00008958 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
8959 return NULL;
8960
8961 errno = 0;
8962 len = confstr(name, buffer, sizeof(buffer));
8963 if (len == 0) {
8964 if (errno) {
8965 posix_error();
8966 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00008967 }
8968 else {
Victor Stinnercb043522010-09-10 23:49:04 +00008969 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00008970 }
8971 }
Victor Stinnercb043522010-09-10 23:49:04 +00008972
8973 if ((unsigned int)len >= sizeof(buffer)) {
8974 char *buf = PyMem_Malloc(len);
8975 if (buf == NULL)
8976 return PyErr_NoMemory();
8977 confstr(name, buf, len);
8978 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
8979 PyMem_Free(buf);
8980 }
8981 else
8982 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00008983 return result;
8984}
8985#endif
8986
8987
8988#ifdef HAVE_SYSCONF
8989static struct constdef posix_constants_sysconf[] = {
8990#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008991 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00008992#endif
8993#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00008994 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00008995#endif
8996#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008997 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008998#endif
8999#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009000 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009001#endif
9002#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009003 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009004#endif
9005#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009006 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009007#endif
9008#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009009 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009010#endif
9011#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009012 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009013#endif
9014#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009015 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009016#endif
9017#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009018 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009019#endif
Fred Draked86ed291999-12-15 15:34:33 +00009020#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009021 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009022#endif
9023#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009024 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009025#endif
Fred Drakec9680921999-12-13 16:37:25 +00009026#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009027 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009028#endif
Fred Drakec9680921999-12-13 16:37:25 +00009029#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009030 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009031#endif
9032#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009033 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009034#endif
9035#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009036 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009037#endif
9038#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009039 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009040#endif
9041#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009042 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009043#endif
Fred Draked86ed291999-12-15 15:34:33 +00009044#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009045 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009046#endif
Fred Drakec9680921999-12-13 16:37:25 +00009047#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009048 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009049#endif
9050#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009051 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009052#endif
9053#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009054 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009055#endif
9056#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009057 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009058#endif
9059#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009060 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009061#endif
Fred Draked86ed291999-12-15 15:34:33 +00009062#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009063 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009064#endif
Fred Drakec9680921999-12-13 16:37:25 +00009065#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009066 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009067#endif
9068#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009069 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009070#endif
9071#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009072 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009073#endif
9074#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009075 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009076#endif
9077#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009078 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009079#endif
9080#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009081 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009082#endif
9083#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009084 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009085#endif
9086#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009087 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009088#endif
9089#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009090 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009091#endif
9092#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009093 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009094#endif
9095#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009096 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009097#endif
9098#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009099 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009100#endif
9101#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009102 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009103#endif
9104#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009105 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009106#endif
9107#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009108 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009109#endif
9110#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009111 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009112#endif
9113#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009114 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009115#endif
9116#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009117 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009118#endif
9119#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009120 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009121#endif
9122#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009123 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009124#endif
9125#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009126 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009127#endif
9128#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009129 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009130#endif
9131#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009132 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009133#endif
Fred Draked86ed291999-12-15 15:34:33 +00009134#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009135 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009136#endif
Fred Drakec9680921999-12-13 16:37:25 +00009137#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009138 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009139#endif
9140#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009141 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009142#endif
9143#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009144 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009145#endif
Fred Draked86ed291999-12-15 15:34:33 +00009146#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009147 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009148#endif
Fred Drakec9680921999-12-13 16:37:25 +00009149#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009150 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009151#endif
Fred Draked86ed291999-12-15 15:34:33 +00009152#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009153 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009154#endif
9155#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009156 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009157#endif
Fred Drakec9680921999-12-13 16:37:25 +00009158#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009159 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009160#endif
9161#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009162 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009163#endif
9164#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009165 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009166#endif
9167#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009168 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009169#endif
Fred Draked86ed291999-12-15 15:34:33 +00009170#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009171 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009172#endif
Fred Drakec9680921999-12-13 16:37:25 +00009173#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009174 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009175#endif
9176#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009177 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009178#endif
9179#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009180 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009181#endif
9182#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009183 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009184#endif
9185#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009186 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009187#endif
9188#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009189 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009190#endif
9191#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009192 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009193#endif
Fred Draked86ed291999-12-15 15:34:33 +00009194#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009195 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009196#endif
Fred Drakec9680921999-12-13 16:37:25 +00009197#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009198 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009199#endif
9200#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009201 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009202#endif
Fred Draked86ed291999-12-15 15:34:33 +00009203#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009204 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009205#endif
Fred Drakec9680921999-12-13 16:37:25 +00009206#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009207 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009208#endif
9209#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009210 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009211#endif
9212#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009213 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009214#endif
9215#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009216 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009217#endif
9218#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009219 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009220#endif
9221#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009222 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009223#endif
9224#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009225 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009226#endif
9227#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009228 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009229#endif
9230#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009231 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009232#endif
Fred Draked86ed291999-12-15 15:34:33 +00009233#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009234 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009235#endif
9236#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009237 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009238#endif
Fred Drakec9680921999-12-13 16:37:25 +00009239#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009240 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009241#endif
9242#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009243 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009244#endif
9245#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009246 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009247#endif
9248#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009249 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009250#endif
9251#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009252 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009253#endif
9254#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009255 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009256#endif
9257#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009258 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009259#endif
9260#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009261 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009262#endif
9263#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009264 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009265#endif
9266#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009267 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009268#endif
9269#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00009270 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00009271#endif
9272#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009273 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00009274#endif
9275#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009276 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00009277#endif
9278#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00009279 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00009280#endif
9281#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00009282 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00009283#endif
9284#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00009285 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00009286#endif
9287#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00009288 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00009289#endif
9290#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009291 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009292#endif
9293#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009294 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009295#endif
9296#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00009297 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00009298#endif
9299#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009300 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009301#endif
9302#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009303 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009304#endif
9305#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00009306 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00009307#endif
9308#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009309 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009310#endif
9311#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009312 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009313#endif
9314#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009315 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00009316#endif
9317#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00009318 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00009319#endif
9320#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009321 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009322#endif
9323#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009324 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009325#endif
9326#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009327 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00009328#endif
9329#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009330 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009331#endif
9332#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009333 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009334#endif
9335#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009336 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009337#endif
9338#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009339 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009340#endif
9341#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009342 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009343#endif
Fred Draked86ed291999-12-15 15:34:33 +00009344#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00009345 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00009346#endif
Fred Drakec9680921999-12-13 16:37:25 +00009347#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00009348 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00009349#endif
9350#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009351 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009352#endif
9353#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00009354 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00009355#endif
9356#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009357 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009358#endif
9359#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009360 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009361#endif
9362#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009363 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009364#endif
9365#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00009366 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00009367#endif
9368#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009369 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009370#endif
9371#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009372 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009373#endif
9374#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009375 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009376#endif
9377#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009378 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009379#endif
9380#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009381 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00009382#endif
9383#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009384 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00009385#endif
9386#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00009387 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00009388#endif
9389#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009390 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009391#endif
9392#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009393 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009394#endif
9395#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009396 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009397#endif
9398#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009399 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00009400#endif
9401#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009402 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009403#endif
9404#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009405 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009406#endif
9407#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009408 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009409#endif
9410#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009411 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009412#endif
9413#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009414 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009415#endif
9416#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009417 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009418#endif
9419#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00009420 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00009421#endif
9422#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009423 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009424#endif
9425#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009426 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009427#endif
9428#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009429 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009430#endif
9431#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009432 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009433#endif
9434#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00009435 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00009436#endif
9437#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009438 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009439#endif
9440#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00009441 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00009442#endif
9443#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009444 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009445#endif
9446#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00009447 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00009448#endif
9449#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00009450 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00009451#endif
9452#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00009453 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00009454#endif
9455#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00009456 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00009457#endif
9458#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009459 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009460#endif
9461#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00009462 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00009463#endif
9464#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00009465 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00009466#endif
9467#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009468 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009469#endif
9470#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009471 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009472#endif
9473#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00009474 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00009475#endif
9476#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00009477 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00009478#endif
9479#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00009480 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00009481#endif
9482};
9483
9484static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009485conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009486{
9487 return conv_confname(arg, valuep, posix_constants_sysconf,
9488 sizeof(posix_constants_sysconf)
9489 / sizeof(struct constdef));
9490}
9491
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009492PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009493"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009494Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009495
9496static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009497posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009498{
9499 PyObject *result = NULL;
9500 int name;
9501
9502 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
9503 int value;
9504
9505 errno = 0;
9506 value = sysconf(name);
9507 if (value == -1 && errno != 0)
9508 posix_error();
9509 else
Christian Heimes217cfd12007-12-02 14:31:20 +00009510 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00009511 }
9512 return result;
9513}
9514#endif
9515
9516
Fred Drakebec628d1999-12-15 18:31:10 +00009517/* This code is used to ensure that the tables of configuration value names
9518 * are in sorted order as required by conv_confname(), and also to build the
9519 * the exported dictionaries that are used to publish information about the
9520 * names available on the host platform.
9521 *
9522 * Sorting the table at runtime ensures that the table is properly ordered
9523 * when used, even for platforms we're not able to test on. It also makes
9524 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00009525 */
Fred Drakebec628d1999-12-15 18:31:10 +00009526
9527static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009528cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00009529{
9530 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009531 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00009532 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009533 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00009534
9535 return strcmp(c1->name, c2->name);
9536}
9537
9538static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009539setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00009540 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009541{
Fred Drakebec628d1999-12-15 18:31:10 +00009542 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00009543 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00009544
9545 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
9546 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00009547 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00009548 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009549
Barry Warsaw3155db32000-04-13 15:20:40 +00009550 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009551 PyObject *o = PyLong_FromLong(table[i].value);
9552 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
9553 Py_XDECREF(o);
9554 Py_DECREF(d);
9555 return -1;
9556 }
9557 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00009558 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00009559 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00009560}
9561
Fred Drakebec628d1999-12-15 18:31:10 +00009562/* Return -1 on failure, 0 on success. */
9563static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00009564setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009565{
9566#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00009567 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00009568 sizeof(posix_constants_pathconf)
9569 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009570 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009571 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009572#endif
9573#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00009574 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00009575 sizeof(posix_constants_confstr)
9576 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009577 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009578 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009579#endif
9580#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00009581 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00009582 sizeof(posix_constants_sysconf)
9583 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009584 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009585 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009586#endif
Fred Drakebec628d1999-12-15 18:31:10 +00009587 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00009588}
Fred Draked86ed291999-12-15 15:34:33 +00009589
9590
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009591PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009592"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009593Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009594in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009595
9596static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009597posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009598{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009599 abort();
9600 /*NOTREACHED*/
9601 Py_FatalError("abort() called from Python code didn't abort!");
9602 return NULL;
9603}
Fred Drakebec628d1999-12-15 18:31:10 +00009604
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00009605#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009606PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00009607"startfile(filepath [, operation]) - Start a file with its associated\n\
9608application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009609\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00009610When \"operation\" is not specified or \"open\", this acts like\n\
9611double-clicking the file in Explorer, or giving the file name as an\n\
9612argument to the DOS \"start\" command: the file is opened with whatever\n\
9613application (if any) its extension is associated.\n\
9614When another \"operation\" is given, it specifies what should be done with\n\
9615the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009616\n\
9617startfile returns as soon as the associated application is launched.\n\
9618There is no option to wait for the application to close, and no way\n\
9619to retrieve the application's exit status.\n\
9620\n\
9621The filepath is relative to the current directory. If you want to use\n\
9622an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009623the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00009624
9625static PyObject *
9626win32_startfile(PyObject *self, PyObject *args)
9627{
Victor Stinner8c62be82010-05-06 00:08:46 +00009628 PyObject *ofilepath;
9629 char *filepath;
9630 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02009631 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +00009632 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00009633
Victor Stinnereb5657a2011-09-30 01:44:27 +02009634 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009635 if (!PyArg_ParseTuple(args, "U|s:startfile",
9636 &unipath, &operation)) {
9637 PyErr_Clear();
9638 goto normal;
9639 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009640
Victor Stinner8c62be82010-05-06 00:08:46 +00009641 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009642 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +00009643 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +02009644 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009645 PyErr_Clear();
9646 operation = NULL;
9647 goto normal;
9648 }
9649 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009650
Victor Stinnereb5657a2011-09-30 01:44:27 +02009651 wpath = PyUnicode_AsUnicode(unipath);
9652 if (wpath == NULL)
9653 goto normal;
9654 if (uoperation) {
9655 woperation = PyUnicode_AsUnicode(uoperation);
9656 if (woperation == NULL)
9657 goto normal;
9658 }
9659 else
9660 woperation = NULL;
9661
Victor Stinner8c62be82010-05-06 00:08:46 +00009662 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02009663 rc = ShellExecuteW((HWND)0, woperation, wpath,
9664 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +00009665 Py_END_ALLOW_THREADS
9666
Victor Stinnereb5657a2011-09-30 01:44:27 +02009667 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +00009668 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009669 win32_error_object("startfile", unipath);
9670 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009671 }
9672 Py_INCREF(Py_None);
9673 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009674
9675normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00009676 if (!PyArg_ParseTuple(args, "O&|s:startfile",
9677 PyUnicode_FSConverter, &ofilepath,
9678 &operation))
9679 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01009680 if (win32_warn_bytes_api()) {
9681 Py_DECREF(ofilepath);
9682 return NULL;
9683 }
Victor Stinner8c62be82010-05-06 00:08:46 +00009684 filepath = PyBytes_AsString(ofilepath);
9685 Py_BEGIN_ALLOW_THREADS
9686 rc = ShellExecute((HWND)0, operation, filepath,
9687 NULL, NULL, SW_SHOWNORMAL);
9688 Py_END_ALLOW_THREADS
9689 if (rc <= (HINSTANCE)32) {
9690 PyObject *errval = win32_error("startfile", filepath);
9691 Py_DECREF(ofilepath);
9692 return errval;
9693 }
9694 Py_DECREF(ofilepath);
9695 Py_INCREF(Py_None);
9696 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00009697}
9698#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009699
Martin v. Löwis438b5342002-12-27 10:16:42 +00009700#ifdef HAVE_GETLOADAVG
9701PyDoc_STRVAR(posix_getloadavg__doc__,
9702"getloadavg() -> (float, float, float)\n\n\
9703Return the number of processes in the system run queue averaged over\n\
9704the last 1, 5, and 15 minutes or raises OSError if the load average\n\
9705was unobtainable");
9706
9707static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009708posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00009709{
9710 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00009711 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009712 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
9713 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00009714 } else
Stefan Krah0e803b32010-11-26 16:16:47 +00009715 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00009716}
9717#endif
9718
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009719PyDoc_STRVAR(device_encoding__doc__,
9720"device_encoding(fd) -> str\n\n\
9721Return a string describing the encoding of the device\n\
9722if the output is a terminal; else return None.");
9723
9724static PyObject *
9725device_encoding(PyObject *self, PyObject *args)
9726{
Victor Stinner8c62be82010-05-06 00:08:46 +00009727 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -05009728
Victor Stinner8c62be82010-05-06 00:08:46 +00009729 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
9730 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -05009731
9732 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009733}
9734
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009735#ifdef HAVE_SETRESUID
9736PyDoc_STRVAR(posix_setresuid__doc__,
9737"setresuid(ruid, euid, suid)\n\n\
9738Set the current process's real, effective, and saved user ids.");
9739
9740static PyObject*
9741posix_setresuid (PyObject *self, PyObject *args)
9742{
Victor Stinner8c62be82010-05-06 00:08:46 +00009743 /* We assume uid_t is no larger than a long. */
9744 long ruid, euid, suid;
9745 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
9746 return NULL;
9747 if (setresuid(ruid, euid, suid) < 0)
9748 return posix_error();
9749 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009750}
9751#endif
9752
9753#ifdef HAVE_SETRESGID
9754PyDoc_STRVAR(posix_setresgid__doc__,
9755"setresgid(rgid, egid, sgid)\n\n\
9756Set the current process's real, effective, and saved group ids.");
9757
9758static PyObject*
9759posix_setresgid (PyObject *self, PyObject *args)
9760{
Victor Stinner8c62be82010-05-06 00:08:46 +00009761 /* We assume uid_t is no larger than a long. */
9762 long rgid, egid, sgid;
9763 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
9764 return NULL;
9765 if (setresgid(rgid, egid, sgid) < 0)
9766 return posix_error();
9767 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009768}
9769#endif
9770
9771#ifdef HAVE_GETRESUID
9772PyDoc_STRVAR(posix_getresuid__doc__,
9773"getresuid() -> (ruid, euid, suid)\n\n\
9774Get tuple of the current process's real, effective, and saved user ids.");
9775
9776static PyObject*
9777posix_getresuid (PyObject *self, PyObject *noargs)
9778{
Victor Stinner8c62be82010-05-06 00:08:46 +00009779 uid_t ruid, euid, suid;
9780 long l_ruid, l_euid, l_suid;
9781 if (getresuid(&ruid, &euid, &suid) < 0)
9782 return posix_error();
9783 /* Force the values into long's as we don't know the size of uid_t. */
9784 l_ruid = ruid;
9785 l_euid = euid;
9786 l_suid = suid;
9787 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009788}
9789#endif
9790
9791#ifdef HAVE_GETRESGID
9792PyDoc_STRVAR(posix_getresgid__doc__,
9793"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00009794Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009795
9796static PyObject*
9797posix_getresgid (PyObject *self, PyObject *noargs)
9798{
Victor Stinner8c62be82010-05-06 00:08:46 +00009799 uid_t rgid, egid, sgid;
9800 long l_rgid, l_egid, l_sgid;
9801 if (getresgid(&rgid, &egid, &sgid) < 0)
9802 return posix_error();
9803 /* Force the values into long's as we don't know the size of uid_t. */
9804 l_rgid = rgid;
9805 l_egid = egid;
9806 l_sgid = sgid;
9807 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009808}
9809#endif
9810
Benjamin Peterson9428d532011-09-14 11:45:52 -04009811#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -04009812
Benjamin Peterson799bd802011-08-31 22:15:17 -04009813PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009814"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
9815Return the value of extended attribute attribute on path.\n\
9816\n\
9817path may be either a string or an open file descriptor.\n\
9818If follow_symlinks is False, and the last element of the path is a symbolic\n\
9819 link, getxattr will examine the symbolic link itself instead of the file\n\
9820 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -04009821
9822static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009823posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04009824{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009825 path_t path;
9826 path_t attribute;
9827 int follow_symlinks = 1;
9828 PyObject *buffer = NULL;
9829 int i;
9830 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -04009831
Larry Hastings9cf065c2012-06-22 16:30:09 -07009832 memset(&path, 0, sizeof(path));
9833 memset(&attribute, 0, sizeof(attribute));
9834 path.allow_fd = 1;
9835 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
9836 path_converter, &path,
9837 path_converter, &attribute,
9838 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -04009839 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009840
Larry Hastings9cf065c2012-06-22 16:30:09 -07009841 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
9842 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009843
Larry Hastings9cf065c2012-06-22 16:30:09 -07009844 for (i = 0; ; i++) {
9845 void *ptr;
9846 ssize_t result;
9847 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
9848 Py_ssize_t buffer_size = buffer_sizes[i];
9849 if (!buffer_size) {
9850 path_error("getxattr", &path);
9851 goto exit;
9852 }
9853 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
9854 if (!buffer)
9855 goto exit;
9856 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009857
Larry Hastings9cf065c2012-06-22 16:30:09 -07009858 Py_BEGIN_ALLOW_THREADS;
9859 if (path.fd >= 0)
9860 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
9861 else if (follow_symlinks)
9862 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
9863 else
9864 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
9865 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009866
Larry Hastings9cf065c2012-06-22 16:30:09 -07009867 if (result < 0) {
9868 Py_DECREF(buffer);
9869 buffer = NULL;
9870 if (errno == ERANGE)
9871 continue;
9872 path_error("getxattr", &path);
9873 goto exit;
9874 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009875
Larry Hastings9cf065c2012-06-22 16:30:09 -07009876 if (result != buffer_size) {
9877 /* Can only shrink. */
9878 _PyBytes_Resize(&buffer, result);
9879 }
9880 break;
9881 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009882
Larry Hastings9cf065c2012-06-22 16:30:09 -07009883exit:
9884 path_cleanup(&path);
9885 path_cleanup(&attribute);
9886 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009887}
9888
9889PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009890"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
9891Set extended attribute attribute on path to value.\n\
9892path may be either a string or an open file descriptor.\n\
9893If follow_symlinks is False, and the last element of the path is a symbolic\n\
9894 link, setxattr will modify the symbolic link itself instead of the file\n\
9895 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -04009896
9897static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009898posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04009899{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009900 path_t path;
9901 path_t attribute;
9902 Py_buffer value;
9903 int flags = 0;
9904 int follow_symlinks = 1;
9905 int result;
9906 PyObject *return_value = NULL;
9907 static char *keywords[] = {"path", "attribute", "value",
9908 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -04009909
Larry Hastings9cf065c2012-06-22 16:30:09 -07009910 memset(&path, 0, sizeof(path));
9911 path.allow_fd = 1;
9912 memset(&attribute, 0, sizeof(attribute));
9913 memset(&value, 0, sizeof(value));
9914 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
9915 keywords,
9916 path_converter, &path,
9917 path_converter, &attribute,
9918 &value, &flags,
9919 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -04009920 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009921
9922 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
9923 goto exit;
9924
Benjamin Peterson799bd802011-08-31 22:15:17 -04009925 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009926 if (path.fd > -1)
9927 result = fsetxattr(path.fd, attribute.narrow,
9928 value.buf, value.len, flags);
9929 else if (follow_symlinks)
9930 result = setxattr(path.narrow, attribute.narrow,
9931 value.buf, value.len, flags);
9932 else
9933 result = lsetxattr(path.narrow, attribute.narrow,
9934 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009935 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009936
Larry Hastings9cf065c2012-06-22 16:30:09 -07009937 if (result) {
9938 return_value = path_error("setxattr", &path);
9939 goto exit;
9940 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009941
Larry Hastings9cf065c2012-06-22 16:30:09 -07009942 return_value = Py_None;
9943 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009944
Larry Hastings9cf065c2012-06-22 16:30:09 -07009945exit:
9946 path_cleanup(&path);
9947 path_cleanup(&attribute);
9948 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009949
Larry Hastings9cf065c2012-06-22 16:30:09 -07009950 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009951}
9952
9953PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009954"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
9955Remove extended attribute attribute on path.\n\
9956path may be either a string or an open file descriptor.\n\
9957If follow_symlinks is False, and the last element of the path is a symbolic\n\
9958 link, removexattr will modify the symbolic link itself instead of the file\n\
9959 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -04009960
9961static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009962posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04009963{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009964 path_t path;
9965 path_t attribute;
9966 int follow_symlinks = 1;
9967 int result;
9968 PyObject *return_value = NULL;
9969 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -04009970
Larry Hastings9cf065c2012-06-22 16:30:09 -07009971 memset(&path, 0, sizeof(path));
9972 memset(&attribute, 0, sizeof(attribute));
9973 path.allow_fd = 1;
9974 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
9975 keywords,
9976 path_converter, &path,
9977 path_converter, &attribute,
9978 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -04009979 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009980
9981 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
9982 goto exit;
9983
Benjamin Peterson799bd802011-08-31 22:15:17 -04009984 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009985 if (path.fd > -1)
9986 result = fremovexattr(path.fd, attribute.narrow);
9987 else if (follow_symlinks)
9988 result = removexattr(path.narrow, attribute.narrow);
9989 else
9990 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009991 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009992
Larry Hastings9cf065c2012-06-22 16:30:09 -07009993 if (result) {
9994 return_value = path_error("removexattr", &path);
9995 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009996 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009997
Larry Hastings9cf065c2012-06-22 16:30:09 -07009998 return_value = Py_None;
9999 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010000
Larry Hastings9cf065c2012-06-22 16:30:09 -070010001exit:
10002 path_cleanup(&path);
10003 path_cleanup(&attribute);
10004
10005 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010006}
10007
10008PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010009"listxattr(path='.', *, follow_symlinks=True)\n\n\
10010Return a list of extended attributes on path.\n\
10011\n\
10012path may be either None, a string, or an open file descriptor.\n\
10013if path is None, listxattr will examine the current directory.\n\
10014If follow_symlinks is False, and the last element of the path is a symbolic\n\
10015 link, listxattr will examine the symbolic link itself instead of the file\n\
10016 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010017
10018static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010019posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010020{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010021 path_t path;
10022 int follow_symlinks = 1;
10023 Py_ssize_t i;
10024 PyObject *result = NULL;
10025 char *buffer = NULL;
10026 char *name;
10027 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010028
Larry Hastings9cf065c2012-06-22 16:30:09 -070010029 memset(&path, 0, sizeof(path));
10030 path.allow_fd = 1;
10031 path.fd = -1;
10032 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10033 path_converter, &path,
10034 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010035 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010036
Larry Hastings9cf065c2012-06-22 16:30:09 -070010037 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10038 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010039
Larry Hastings9cf065c2012-06-22 16:30:09 -070010040 name = path.narrow ? path.narrow : ".";
10041 for (i = 0; ; i++) {
10042 char *start, *trace, *end;
10043 ssize_t length;
10044 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10045 Py_ssize_t buffer_size = buffer_sizes[i];
10046 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010047 /* ERANGE */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010048 path_error("listxattr", &path);
10049 break;
10050 }
10051 buffer = PyMem_MALLOC(buffer_size);
10052 if (!buffer) {
10053 PyErr_NoMemory();
10054 break;
10055 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010056
Larry Hastings9cf065c2012-06-22 16:30:09 -070010057 Py_BEGIN_ALLOW_THREADS;
10058 if (path.fd > -1)
10059 length = flistxattr(path.fd, buffer, buffer_size);
10060 else if (follow_symlinks)
10061 length = listxattr(name, buffer, buffer_size);
10062 else
10063 length = llistxattr(name, buffer, buffer_size);
10064 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010065
Larry Hastings9cf065c2012-06-22 16:30:09 -070010066 if (length < 0) {
10067 if (errno == ERANGE)
10068 continue;
10069 path_error("listxattr", &path);
10070 break;
10071 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010072
Larry Hastings9cf065c2012-06-22 16:30:09 -070010073 result = PyList_New(0);
10074 if (!result) {
10075 goto exit;
10076 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010077
Larry Hastings9cf065c2012-06-22 16:30:09 -070010078 end = buffer + length;
10079 for (trace = start = buffer; trace != end; trace++) {
10080 if (!*trace) {
10081 int error;
10082 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10083 trace - start);
10084 if (!attribute) {
10085 Py_DECREF(result);
10086 result = NULL;
10087 goto exit;
10088 }
10089 error = PyList_Append(result, attribute);
10090 Py_DECREF(attribute);
10091 if (error) {
10092 Py_DECREF(result);
10093 result = NULL;
10094 goto exit;
10095 }
10096 start = trace + 1;
10097 }
10098 }
10099 break;
10100 }
10101exit:
10102 path_cleanup(&path);
10103 if (buffer)
10104 PyMem_FREE(buffer);
10105 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010106}
10107
Benjamin Peterson9428d532011-09-14 11:45:52 -040010108#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010109
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010110
Georg Brandl2fb477c2012-02-21 00:33:36 +010010111PyDoc_STRVAR(posix_urandom__doc__,
10112"urandom(n) -> str\n\n\
10113Return n random bytes suitable for cryptographic use.");
10114
10115static PyObject *
10116posix_urandom(PyObject *self, PyObject *args)
10117{
10118 Py_ssize_t size;
10119 PyObject *result;
10120 int ret;
10121
10122 /* Read arguments */
10123 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10124 return NULL;
10125 if (size < 0)
10126 return PyErr_Format(PyExc_ValueError,
10127 "negative argument not allowed");
10128 result = PyBytes_FromStringAndSize(NULL, size);
10129 if (result == NULL)
10130 return NULL;
10131
10132 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10133 PyBytes_GET_SIZE(result));
10134 if (ret == -1) {
10135 Py_DECREF(result);
10136 return NULL;
10137 }
10138 return result;
10139}
10140
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010141/* Terminal size querying */
10142
10143static PyTypeObject TerminalSizeType;
10144
10145PyDoc_STRVAR(TerminalSize_docstring,
10146 "A tuple of (columns, lines) for holding terminal window size");
10147
10148static PyStructSequence_Field TerminalSize_fields[] = {
10149 {"columns", "width of the terminal window in characters"},
10150 {"lines", "height of the terminal window in characters"},
10151 {NULL, NULL}
10152};
10153
10154static PyStructSequence_Desc TerminalSize_desc = {
10155 "os.terminal_size",
10156 TerminalSize_docstring,
10157 TerminalSize_fields,
10158 2,
10159};
10160
10161#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10162PyDoc_STRVAR(termsize__doc__,
10163 "Return the size of the terminal window as (columns, lines).\n" \
10164 "\n" \
10165 "The optional argument fd (default standard output) specifies\n" \
10166 "which file descriptor should be queried.\n" \
10167 "\n" \
10168 "If the file descriptor is not connected to a terminal, an OSError\n" \
10169 "is thrown.\n" \
10170 "\n" \
10171 "This function will only be defined if an implementation is\n" \
10172 "available for this system.\n" \
10173 "\n" \
10174 "shutil.get_terminal_size is the high-level function which should \n" \
10175 "normally be used, os.get_terminal_size is the low-level implementation.");
10176
10177static PyObject*
10178get_terminal_size(PyObject *self, PyObject *args)
10179{
10180 int columns, lines;
10181 PyObject *termsize;
10182
10183 int fd = fileno(stdout);
10184 /* Under some conditions stdout may not be connected and
10185 * fileno(stdout) may point to an invalid file descriptor. For example
10186 * GUI apps don't have valid standard streams by default.
10187 *
10188 * If this happens, and the optional fd argument is not present,
10189 * the ioctl below will fail returning EBADF. This is what we want.
10190 */
10191
10192 if (!PyArg_ParseTuple(args, "|i", &fd))
10193 return NULL;
10194
10195#ifdef TERMSIZE_USE_IOCTL
10196 {
10197 struct winsize w;
10198 if (ioctl(fd, TIOCGWINSZ, &w))
10199 return PyErr_SetFromErrno(PyExc_OSError);
10200 columns = w.ws_col;
10201 lines = w.ws_row;
10202 }
10203#endif /* TERMSIZE_USE_IOCTL */
10204
10205#ifdef TERMSIZE_USE_CONIO
10206 {
10207 DWORD nhandle;
10208 HANDLE handle;
10209 CONSOLE_SCREEN_BUFFER_INFO csbi;
10210 switch (fd) {
10211 case 0: nhandle = STD_INPUT_HANDLE;
10212 break;
10213 case 1: nhandle = STD_OUTPUT_HANDLE;
10214 break;
10215 case 2: nhandle = STD_ERROR_HANDLE;
10216 break;
10217 default:
10218 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10219 }
10220 handle = GetStdHandle(nhandle);
10221 if (handle == NULL)
10222 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10223 if (handle == INVALID_HANDLE_VALUE)
10224 return PyErr_SetFromWindowsErr(0);
10225
10226 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10227 return PyErr_SetFromWindowsErr(0);
10228
10229 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10230 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10231 }
10232#endif /* TERMSIZE_USE_CONIO */
10233
10234 termsize = PyStructSequence_New(&TerminalSizeType);
10235 if (termsize == NULL)
10236 return NULL;
10237 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10238 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10239 if (PyErr_Occurred()) {
10240 Py_DECREF(termsize);
10241 return NULL;
10242 }
10243 return termsize;
10244}
10245#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10246
10247
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010248static PyMethodDef posix_methods[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010249 {"access", (PyCFunction)posix_access,
10250 METH_VARARGS | METH_KEYWORDS,
10251 posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010252#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010253 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010254#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010255 {"chdir", (PyCFunction)posix_chdir,
10256 METH_VARARGS | METH_KEYWORDS,
10257 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010258#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010259 {"chflags", (PyCFunction)posix_chflags,
10260 METH_VARARGS | METH_KEYWORDS,
10261 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010262#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010263 {"chmod", (PyCFunction)posix_chmod,
10264 METH_VARARGS | METH_KEYWORDS,
10265 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010266#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010267 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010268#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010269#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070010270 {"chown", (PyCFunction)posix_chown,
10271 METH_VARARGS | METH_KEYWORDS,
10272 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010273#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010274#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010275 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010276#endif /* HAVE_LCHMOD */
10277#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010278 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010279#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010280#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010281 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010282#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010283#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010284 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010285#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010286#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010287 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010288#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010289#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010290 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010291#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010292#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010293 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10294 METH_NOARGS, posix_getcwd__doc__},
10295 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10296 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010297#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010298#if defined(HAVE_LINK) || defined(MS_WINDOWS)
10299 {"link", (PyCFunction)posix_link,
10300 METH_VARARGS | METH_KEYWORDS,
10301 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010302#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010303 {"listdir", (PyCFunction)posix_listdir,
10304 METH_VARARGS | METH_KEYWORDS,
10305 posix_listdir__doc__},
10306 {"lstat", (PyCFunction)posix_lstat,
10307 METH_VARARGS | METH_KEYWORDS,
10308 posix_lstat__doc__},
10309 {"mkdir", (PyCFunction)posix_mkdir,
10310 METH_VARARGS | METH_KEYWORDS,
10311 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010312#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010313 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000010314#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010315#ifdef HAVE_GETPRIORITY
10316 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10317#endif /* HAVE_GETPRIORITY */
10318#ifdef HAVE_SETPRIORITY
10319 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10320#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010321#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070010322 {"readlink", (PyCFunction)posix_readlink,
10323 METH_VARARGS | METH_KEYWORDS,
10324 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010325#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010326#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010327 {"readlink", (PyCFunction)win_readlink,
10328 METH_VARARGS | METH_KEYWORDS,
10329 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010330#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010331 {"rename", (PyCFunction)posix_rename,
10332 METH_VARARGS | METH_KEYWORDS,
10333 posix_rename__doc__},
10334 {"replace", (PyCFunction)posix_replace,
10335 METH_VARARGS | METH_KEYWORDS,
10336 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070010337 {"rmdir", (PyCFunction)posix_rmdir,
10338 METH_VARARGS | METH_KEYWORDS,
10339 posix_rmdir__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010340 {"stat", (PyCFunction)posix_stat,
10341 METH_VARARGS | METH_KEYWORDS,
10342 posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010343 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010344#if defined(HAVE_SYMLINK)
10345 {"symlink", (PyCFunction)posix_symlink,
10346 METH_VARARGS | METH_KEYWORDS,
10347 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010348#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000010349#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010350 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010351#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010352 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010353#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010354 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010355#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010356 {"unlink", (PyCFunction)posix_unlink,
10357 METH_VARARGS | METH_KEYWORDS,
10358 posix_unlink__doc__},
10359 {"remove", (PyCFunction)posix_unlink,
10360 METH_VARARGS | METH_KEYWORDS,
10361 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070010362 {"utime", (PyCFunction)posix_utime,
10363 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000010364#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010365 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010366#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010367 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010368#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010369 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010370 {"execve", (PyCFunction)posix_execve,
10371 METH_VARARGS | METH_KEYWORDS,
10372 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010373#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000010374#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010375 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10376 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +000010377#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010378#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010379 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010380#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010381#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010382 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010383#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010384#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010385#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010386 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
10387 {"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 +020010388#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010389#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010390 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010391#endif
10392#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010393 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010394#endif
10395#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010396 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010397#endif
10398#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010399 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010400#endif
10401#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010402 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010403#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010404 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050010405#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010406 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
10407 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
10408#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010409#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010410#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000010411 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010412#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000010413#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010414 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000010415#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000010416#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010417 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000010418#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010419#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010420 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000010421#endif /* HAVE_GETEUID */
10422#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010423 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010424#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020010425#ifdef HAVE_GETGROUPLIST
10426 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
10427#endif
Fred Drakec9680921999-12-13 16:37:25 +000010428#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010429 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010430#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010431 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010432#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010433 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010434#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010435#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010436 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010437#endif /* HAVE_GETPPID */
10438#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010439 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010440#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000010441#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010442 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000010443#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000010444#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000010445 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010446#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010447#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000010448 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010449#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000010450#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010451 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000010452#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000010453#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010454 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
10455 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000010456#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010457#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010458 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010459#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010460#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010461 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010462#endif /* HAVE_SETEUID */
10463#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010464 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010465#endif /* HAVE_SETEGID */
10466#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010467 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010468#endif /* HAVE_SETREUID */
10469#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010470 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010471#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010472#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010473 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010474#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010475#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010476 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010477#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000010478#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010479 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000010480#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000010481#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010482 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000010483#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010484#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010485 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010486#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010487#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010488 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010489#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010490#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010010491 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010492#endif /* HAVE_WAIT3 */
10493#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010010494 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010495#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010496#if defined(HAVE_WAITID) && !defined(__APPLE__)
10497 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
10498#endif
Tim Petersab034fa2002-02-01 11:27:43 +000010499#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010500 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010501#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010502#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010503 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010504#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010505#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010506 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010507#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010508#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010509 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010510#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010511#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010512 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010513#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010514#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010515 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010516#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010517 {"open", (PyCFunction)posix_open,\
10518 METH_VARARGS | METH_KEYWORDS,
10519 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010520 {"close", posix_close, METH_VARARGS, posix_close__doc__},
10521 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
10522 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
10523 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
10524 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010525#ifdef HAVE_LOCKF
10526 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
10527#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010528 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
10529 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010530#ifdef HAVE_READV
10531 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
10532#endif
10533#ifdef HAVE_PREAD
10534 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
10535#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010536 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010537#ifdef HAVE_WRITEV
10538 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
10539#endif
10540#ifdef HAVE_PWRITE
10541 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
10542#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000010543#ifdef HAVE_SENDFILE
10544 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
10545 posix_sendfile__doc__},
10546#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010010547 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010548 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010549#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010550 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010551#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010552#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020010553 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010554#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010555#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070010556 {"mkfifo", (PyCFunction)posix_mkfifo,
10557 METH_VARARGS | METH_KEYWORDS,
10558 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010559#endif
Neal Norwitz11690112002-07-30 01:08:28 +000010560#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010561 {"mknod", (PyCFunction)posix_mknod,
10562 METH_VARARGS | METH_KEYWORDS,
10563 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000010564#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010565#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000010566 {"major", posix_major, METH_VARARGS, posix_major__doc__},
10567 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
10568 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010569#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010570#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000010571 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010572#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010573#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020010574 {"truncate", (PyCFunction)posix_truncate,
10575 METH_VARARGS | METH_KEYWORDS,
10576 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010577#endif
10578#ifdef HAVE_POSIX_FALLOCATE
10579 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
10580#endif
10581#ifdef HAVE_POSIX_FADVISE
10582 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
10583#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010584#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010585 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010586#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010587#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010588 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000010589#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010590 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010591#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000010592 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010593#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010594#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010595 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010596#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010597#ifdef HAVE_SYNC
10598 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
10599#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010600#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010601 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010602#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000010603#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010604#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000010605 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000010606#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010607#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000010608 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010609#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000010610#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000010611 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010612#endif /* WIFSTOPPED */
10613#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000010614 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010615#endif /* WIFSIGNALED */
10616#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000010617 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010618#endif /* WIFEXITED */
10619#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000010620 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010621#endif /* WEXITSTATUS */
10622#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010623 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010624#endif /* WTERMSIG */
10625#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010626 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010627#endif /* WSTOPSIG */
10628#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000010629#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000010630 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010631#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000010632#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010633 {"statvfs", (PyCFunction)posix_statvfs,
10634 METH_VARARGS | METH_KEYWORDS,
10635 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010636#endif
Fred Drakec9680921999-12-13 16:37:25 +000010637#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000010638 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010639#endif
10640#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010641 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010642#endif
10643#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010644 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010645#endif
10646#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020010647 {"pathconf", (PyCFunction)posix_pathconf,
10648 METH_VARARGS | METH_KEYWORDS,
10649 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010650#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010651 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010652#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010653 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000010654 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +000010655 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050010656 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010657 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000010658#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000010659#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000010660 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000010661#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010010662 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010663#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010664 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010665#endif
10666#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010667 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010668#endif
10669#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010670 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010671#endif
10672#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010673 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010674#endif
10675
Benjamin Peterson9428d532011-09-14 11:45:52 -040010676#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010677 {"setxattr", (PyCFunction)posix_setxattr,
10678 METH_VARARGS | METH_KEYWORDS,
10679 posix_setxattr__doc__},
10680 {"getxattr", (PyCFunction)posix_getxattr,
10681 METH_VARARGS | METH_KEYWORDS,
10682 posix_getxattr__doc__},
10683 {"removexattr", (PyCFunction)posix_removexattr,
10684 METH_VARARGS | METH_KEYWORDS,
10685 posix_removexattr__doc__},
10686 {"listxattr", (PyCFunction)posix_listxattr,
10687 METH_VARARGS | METH_KEYWORDS,
10688 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040010689#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010690#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10691 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
10692#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010693 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010694};
10695
10696
Barry Warsaw4a342091996-12-19 23:50:02 +000010697static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010698ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000010699{
Victor Stinner8c62be82010-05-06 00:08:46 +000010700 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000010701}
10702
Brian Curtin52173d42010-12-02 18:29:18 +000010703#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000010704static int
Brian Curtin52173d42010-12-02 18:29:18 +000010705enable_symlink()
10706{
10707 HANDLE tok;
10708 TOKEN_PRIVILEGES tok_priv;
10709 LUID luid;
10710 int meth_idx = 0;
10711
10712 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000010713 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000010714
10715 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000010716 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000010717
10718 tok_priv.PrivilegeCount = 1;
10719 tok_priv.Privileges[0].Luid = luid;
10720 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
10721
10722 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
10723 sizeof(TOKEN_PRIVILEGES),
10724 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000010725 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000010726
Brian Curtin3b4499c2010-12-28 14:31:47 +000010727 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
10728 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000010729}
10730#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
10731
Barry Warsaw4a342091996-12-19 23:50:02 +000010732static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000010733all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000010734{
Guido van Rossum94f6f721999-01-06 18:42:14 +000010735#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010736 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010737#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010738#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010739 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010740#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010741#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010742 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010743#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010744#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010745 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010746#endif
Fred Drakec9680921999-12-13 16:37:25 +000010747#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010748 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000010749#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010750#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010751 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010752#endif
Fred Drake106c1a02002-04-23 15:58:02 +000010753#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000010754 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000010755#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000010756#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000010757 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010758#endif
Fred Drake106c1a02002-04-23 15:58:02 +000010759#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000010760 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000010761#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000010762#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000010763 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010764#endif
10765#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000010766 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010767#endif
10768#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000010769 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010770#endif
10771#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000010772 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010773#endif
10774#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010775 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010776#endif
10777#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000010778 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010779#endif
10780#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010781 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010782#endif
10783#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010784 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010785#endif
10786#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010787 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010788#endif
10789#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010790 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010791#endif
10792#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000010793 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010794#endif
10795#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000010796 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010797#endif
10798#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010799 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010800#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000010801#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000010802 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000010803#endif
10804#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000010805 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000010806#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020010807#ifdef O_XATTR
10808 if (ins(d, "O_XATTR", (long)O_XATTR)) return -1;
10809#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010810#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000010811 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010812#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000010813#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010814 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000010815#endif
10816#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010817 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000010818#endif
Jesus Ceacf381202012-04-24 20:44:40 +020010819#ifdef O_EXEC
10820 if (ins(d, "O_EXEC", (long)O_EXEC)) return -1;
10821#endif
10822#ifdef O_SEARCH
10823 if (ins(d, "O_SEARCH", (long)O_SEARCH)) return -1;
10824#endif
10825#ifdef O_TTY_INIT
10826 if (ins(d, "O_TTY_INIT", (long)O_TTY_INIT)) return -1;
10827#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010828#ifdef PRIO_PROCESS
10829 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
10830#endif
10831#ifdef PRIO_PGRP
10832 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
10833#endif
10834#ifdef PRIO_USER
10835 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
10836#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020010837#ifdef O_CLOEXEC
10838 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
10839#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020010840#ifdef O_ACCMODE
10841 if (ins(d, "O_ACCMODE", (long)O_ACCMODE)) return -1;
10842#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010843
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010844
Jesus Cea94363612012-06-22 18:32:07 +020010845#ifdef SEEK_HOLE
10846 if (ins(d, "SEEK_HOLE", (long)SEEK_HOLE)) return -1;
10847#endif
10848#ifdef SEEK_DATA
10849 if (ins(d, "SEEK_DATA", (long)SEEK_DATA)) return -1;
10850#endif
10851
Tim Peters5aa91602002-01-30 05:46:57 +000010852/* MS Windows */
10853#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010854 /* Don't inherit in child processes. */
10855 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010856#endif
10857#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000010858 /* Optimize for short life (keep in memory). */
10859 /* MS forgot to define this one with a non-underscore form too. */
10860 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010861#endif
10862#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000010863 /* Automatically delete when last handle is closed. */
10864 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010865#endif
10866#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000010867 /* Optimize for random access. */
10868 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010869#endif
10870#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010871 /* Optimize for sequential access. */
10872 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010873#endif
10874
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010875/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000010876#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010877 /* Send a SIGIO signal whenever input or output
10878 becomes available on file descriptor */
10879 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000010880#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010881#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010882 /* Direct disk access. */
10883 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010884#endif
10885#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000010886 /* Must be a directory. */
10887 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010888#endif
10889#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000010890 /* Do not follow links. */
10891 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010892#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020010893#ifdef O_NOLINKS
10894 /* Fails if link count of the named file is greater than 1 */
10895 if (ins(d, "O_NOLINKS", (long)O_NOLINKS)) return -1;
10896#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000010897#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010898 /* Do not update the access time. */
10899 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000010900#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000010901
Victor Stinner8c62be82010-05-06 00:08:46 +000010902 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010903#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010904 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010905#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010906#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010907 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010908#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010909#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000010910 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010911#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010912#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010913 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010914#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010915#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000010916 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010917#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010918#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000010919 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010920#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010921#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010922 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010923#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010924#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000010925 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010926#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010927#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000010928 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010929#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010930#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000010931 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010932#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010933#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000010934 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010935#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010936#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000010937 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010938#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010939#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000010940 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010941#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010942#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000010943 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010944#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010945#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010946 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010947#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010948#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010949 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010950#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010951#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000010952 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010953#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010954
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000010955 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000010956#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000010957 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000010958#endif /* ST_RDONLY */
10959#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000010960 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000010961#endif /* ST_NOSUID */
10962
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000010963 /* FreeBSD sendfile() constants */
10964#ifdef SF_NODISKIO
10965 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
10966#endif
10967#ifdef SF_MNOWAIT
10968 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
10969#endif
10970#ifdef SF_SYNC
10971 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
10972#endif
10973
Ross Lagerwall7807c352011-03-17 20:20:30 +020010974 /* constants for posix_fadvise */
10975#ifdef POSIX_FADV_NORMAL
10976 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
10977#endif
10978#ifdef POSIX_FADV_SEQUENTIAL
10979 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
10980#endif
10981#ifdef POSIX_FADV_RANDOM
10982 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
10983#endif
10984#ifdef POSIX_FADV_NOREUSE
10985 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
10986#endif
10987#ifdef POSIX_FADV_WILLNEED
10988 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
10989#endif
10990#ifdef POSIX_FADV_DONTNEED
10991 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
10992#endif
10993
10994 /* constants for waitid */
10995#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
10996 if (ins(d, "P_PID", (long)P_PID)) return -1;
10997 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
10998 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
10999#endif
11000#ifdef WEXITED
11001 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
11002#endif
11003#ifdef WNOWAIT
11004 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
11005#endif
11006#ifdef WSTOPPED
11007 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
11008#endif
11009#ifdef CLD_EXITED
11010 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
11011#endif
11012#ifdef CLD_DUMPED
11013 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
11014#endif
11015#ifdef CLD_TRAPPED
11016 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
11017#endif
11018#ifdef CLD_CONTINUED
11019 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
11020#endif
11021
11022 /* constants for lockf */
11023#ifdef F_LOCK
11024 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
11025#endif
11026#ifdef F_TLOCK
11027 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
11028#endif
11029#ifdef F_ULOCK
11030 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
11031#endif
11032#ifdef F_TEST
11033 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
11034#endif
11035
Guido van Rossum246bc171999-02-01 23:54:31 +000011036#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000011037 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
11038 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
11039 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
11040 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
11041 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011042#endif
11043
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011044#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011045 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011046 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11047 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11048#ifdef SCHED_SPORADIC
11049 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
11050#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011051#ifdef SCHED_BATCH
11052 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11053#endif
11054#ifdef SCHED_IDLE
11055 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11056#endif
11057#ifdef SCHED_RESET_ON_FORK
11058 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11059#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011060#ifdef SCHED_SYS
11061 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11062#endif
11063#ifdef SCHED_IA
11064 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11065#endif
11066#ifdef SCHED_FSS
11067 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11068#endif
11069#ifdef SCHED_FX
11070 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11071#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011072#endif
11073
Benjamin Peterson9428d532011-09-14 11:45:52 -040011074#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011075 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11076 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11077 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11078#endif
11079
Victor Stinner8b905bd2011-10-25 13:34:04 +020011080#ifdef RTLD_LAZY
11081 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11082#endif
11083#ifdef RTLD_NOW
11084 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11085#endif
11086#ifdef RTLD_GLOBAL
11087 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11088#endif
11089#ifdef RTLD_LOCAL
11090 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11091#endif
11092#ifdef RTLD_NODELETE
11093 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11094#endif
11095#ifdef RTLD_NOLOAD
11096 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11097#endif
11098#ifdef RTLD_DEEPBIND
11099 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11100#endif
11101
Victor Stinner8c62be82010-05-06 00:08:46 +000011102 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011103}
11104
11105
Tim Peters5aa91602002-01-30 05:46:57 +000011106#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011107#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011108#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011109
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011110#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011111#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011112#define MODNAME "posix"
11113#endif
11114
Martin v. Löwis1a214512008-06-11 05:26:20 +000011115static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011116 PyModuleDef_HEAD_INIT,
11117 MODNAME,
11118 posix__doc__,
11119 -1,
11120 posix_methods,
11121 NULL,
11122 NULL,
11123 NULL,
11124 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011125};
11126
11127
Larry Hastings9cf065c2012-06-22 16:30:09 -070011128static char *have_functions[] = {
11129
11130#ifdef HAVE_FACCESSAT
11131 "HAVE_FACCESSAT",
11132#endif
11133
11134#ifdef HAVE_FCHDIR
11135 "HAVE_FCHDIR",
11136#endif
11137
11138#ifdef HAVE_FCHMOD
11139 "HAVE_FCHMOD",
11140#endif
11141
11142#ifdef HAVE_FCHMODAT
11143 "HAVE_FCHMODAT",
11144#endif
11145
11146#ifdef HAVE_FCHOWN
11147 "HAVE_FCHOWN",
11148#endif
11149
11150#ifdef HAVE_FEXECVE
11151 "HAVE_FEXECVE",
11152#endif
11153
11154#ifdef HAVE_FDOPENDIR
11155 "HAVE_FDOPENDIR",
11156#endif
11157
Georg Brandl306336b2012-06-24 12:55:33 +020011158#ifdef HAVE_FPATHCONF
11159 "HAVE_FPATHCONF",
11160#endif
11161
Larry Hastings9cf065c2012-06-22 16:30:09 -070011162#ifdef HAVE_FSTATAT
11163 "HAVE_FSTATAT",
11164#endif
11165
11166#ifdef HAVE_FSTATVFS
11167 "HAVE_FSTATVFS",
11168#endif
11169
Georg Brandl306336b2012-06-24 12:55:33 +020011170#ifdef HAVE_FTRUNCATE
11171 "HAVE_FTRUNCATE",
11172#endif
11173
Larry Hastings9cf065c2012-06-22 16:30:09 -070011174#ifdef HAVE_FUTIMENS
11175 "HAVE_FUTIMENS",
11176#endif
11177
11178#ifdef HAVE_FUTIMES
11179 "HAVE_FUTIMES",
11180#endif
11181
11182#ifdef HAVE_FUTIMESAT
11183 "HAVE_FUTIMESAT",
11184#endif
11185
11186#ifdef HAVE_LINKAT
11187 "HAVE_LINKAT",
11188#endif
11189
11190#ifdef HAVE_LCHFLAGS
11191 "HAVE_LCHFLAGS",
11192#endif
11193
11194#ifdef HAVE_LCHMOD
11195 "HAVE_LCHMOD",
11196#endif
11197
11198#ifdef HAVE_LCHOWN
11199 "HAVE_LCHOWN",
11200#endif
11201
11202#ifdef HAVE_LSTAT
11203 "HAVE_LSTAT",
11204#endif
11205
11206#ifdef HAVE_LUTIMES
11207 "HAVE_LUTIMES",
11208#endif
11209
11210#ifdef HAVE_MKDIRAT
11211 "HAVE_MKDIRAT",
11212#endif
11213
11214#ifdef HAVE_MKFIFOAT
11215 "HAVE_MKFIFOAT",
11216#endif
11217
11218#ifdef HAVE_MKNODAT
11219 "HAVE_MKNODAT",
11220#endif
11221
11222#ifdef HAVE_OPENAT
11223 "HAVE_OPENAT",
11224#endif
11225
11226#ifdef HAVE_READLINKAT
11227 "HAVE_READLINKAT",
11228#endif
11229
11230#ifdef HAVE_RENAMEAT
11231 "HAVE_RENAMEAT",
11232#endif
11233
11234#ifdef HAVE_SYMLINKAT
11235 "HAVE_SYMLINKAT",
11236#endif
11237
11238#ifdef HAVE_UNLINKAT
11239 "HAVE_UNLINKAT",
11240#endif
11241
11242#ifdef HAVE_UTIMENSAT
11243 "HAVE_UTIMENSAT",
11244#endif
11245
11246#ifdef MS_WINDOWS
11247 "MS_WINDOWS",
11248#endif
11249
11250 NULL
11251};
11252
11253
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011254PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011255INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011256{
Victor Stinner8c62be82010-05-06 00:08:46 +000011257 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011258 PyObject *list;
11259 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000011260
Brian Curtin52173d42010-12-02 18:29:18 +000011261#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011262 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011263#endif
11264
Victor Stinner8c62be82010-05-06 00:08:46 +000011265 m = PyModule_Create(&posixmodule);
11266 if (m == NULL)
11267 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011268
Victor Stinner8c62be82010-05-06 00:08:46 +000011269 /* Initialize environ dictionary */
11270 v = convertenviron();
11271 Py_XINCREF(v);
11272 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11273 return NULL;
11274 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011275
Victor Stinner8c62be82010-05-06 00:08:46 +000011276 if (all_ins(m))
11277 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011278
Victor Stinner8c62be82010-05-06 00:08:46 +000011279 if (setup_confname_tables(m))
11280 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011281
Victor Stinner8c62be82010-05-06 00:08:46 +000011282 Py_INCREF(PyExc_OSError);
11283 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011284
Guido van Rossumb3d39562000-01-31 18:41:26 +000011285#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011286 if (posix_putenv_garbage == NULL)
11287 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011288#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011289
Victor Stinner8c62be82010-05-06 00:08:46 +000011290 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011291#if defined(HAVE_WAITID) && !defined(__APPLE__)
11292 waitid_result_desc.name = MODNAME ".waitid_result";
11293 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
11294#endif
11295
Victor Stinner8c62be82010-05-06 00:08:46 +000011296 stat_result_desc.name = MODNAME ".stat_result";
11297 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11298 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11299 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
11300 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
11301 structseq_new = StatResultType.tp_new;
11302 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011303
Victor Stinner8c62be82010-05-06 00:08:46 +000011304 statvfs_result_desc.name = MODNAME ".statvfs_result";
11305 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011306#ifdef NEED_TICKS_PER_SECOND
11307# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011308 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011309# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011310 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011311# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011312 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011313# endif
11314#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011315
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050011316#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011317 sched_param_desc.name = MODNAME ".sched_param";
11318 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
11319 SchedParamType.tp_new = sched_param_new;
11320#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011321
11322 /* initialize TerminalSize_info */
11323 PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc);
Victor Stinner8c62be82010-05-06 00:08:46 +000011324 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011325#if defined(HAVE_WAITID) && !defined(__APPLE__)
11326 Py_INCREF((PyObject*) &WaitidResultType);
11327 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
11328#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011329 Py_INCREF((PyObject*) &StatResultType);
11330 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11331 Py_INCREF((PyObject*) &StatVFSResultType);
11332 PyModule_AddObject(m, "statvfs_result",
11333 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011334
11335#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011336 Py_INCREF(&SchedParamType);
11337 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011338#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011339
Larry Hastings605a62d2012-06-24 04:33:36 -070011340 times_result_desc.name = MODNAME ".times_result";
11341 PyStructSequence_InitType(&TimesResultType, &times_result_desc);
11342 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
11343
11344 uname_result_desc.name = MODNAME ".uname_result";
11345 PyStructSequence_InitType(&UnameResultType, &uname_result_desc);
11346 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
11347
Thomas Wouters477c8d52006-05-27 19:21:47 +000011348#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000011349 /*
11350 * Step 2 of weak-linking support on Mac OS X.
11351 *
11352 * The code below removes functions that are not available on the
11353 * currently active platform.
11354 *
11355 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070011356 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000011357 * OSX 10.4.
11358 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011359#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011360 if (fstatvfs == NULL) {
11361 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
11362 return NULL;
11363 }
11364 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011365#endif /* HAVE_FSTATVFS */
11366
11367#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011368 if (statvfs == NULL) {
11369 if (PyObject_DelAttrString(m, "statvfs") == -1) {
11370 return NULL;
11371 }
11372 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011373#endif /* HAVE_STATVFS */
11374
11375# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011376 if (lchown == NULL) {
11377 if (PyObject_DelAttrString(m, "lchown") == -1) {
11378 return NULL;
11379 }
11380 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011381#endif /* HAVE_LCHOWN */
11382
11383
11384#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011385
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020011386 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011387 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
11388
Larry Hastings6fe20b32012-04-19 15:07:49 -070011389 billion = PyLong_FromLong(1000000000);
11390 if (!billion)
11391 return NULL;
11392
Larry Hastings9cf065c2012-06-22 16:30:09 -070011393 /* suppress "function not used" warnings */
11394 {
11395 int ignored;
11396 fd_specified("", -1);
11397 follow_symlinks_specified("", 1);
11398 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
11399 dir_fd_converter(Py_None, &ignored);
11400 dir_fd_unavailable(Py_None, &ignored);
11401 }
11402
11403 /*
11404 * provide list of locally available functions
11405 * so os.py can populate support_* lists
11406 */
11407 list = PyList_New(0);
11408 if (!list)
11409 return NULL;
11410 for (trace = have_functions; *trace; trace++) {
11411 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
11412 if (!unicode)
11413 return NULL;
11414 if (PyList_Append(list, unicode))
11415 return NULL;
11416 Py_DECREF(unicode);
11417 }
11418 PyModule_AddObject(m, "_have_functions", list);
11419
11420 initialized = 1;
11421
Victor Stinner8c62be82010-05-06 00:08:46 +000011422 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011423
Guido van Rossumb6775db1994-08-01 11:34:53 +000011424}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011425
11426#ifdef __cplusplus
11427}
11428#endif