blob: 0aebf17412fe7b4340f29b8c9fd58e6374c5287a [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Guido van Rossuma4916fa1996-05-23 22:58:55 +000014/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000015
Thomas Wouters477c8d52006-05-27 19:21:47 +000016#ifdef __APPLE__
17 /*
18 * Step 1 of support for weak-linking a number of symbols existing on
19 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
20 * at the end of this file for more information.
21 */
22# pragma weak lchown
23# pragma weak statvfs
24# pragma weak fstatvfs
25
26#endif /* __APPLE__ */
27
Thomas Wouters68bc4f92006-03-01 01:05:10 +000028#define PY_SSIZE_T_CLEAN
29
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000030#include "Python.h"
31#include "structseq.h"
32
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000034# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000035#endif /* defined(__VMS) */
36
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000037#ifdef __cplusplus
38extern "C" {
39#endif
40
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000041PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000042"This module provides access to operating system functionality that is\n\
43standardized by the C Standard and the POSIX standard (a thinly\n\
44disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000045corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000046
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000047
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000048#if defined(PYOS_OS2)
49#define INCL_DOS
50#define INCL_DOSERRORS
51#define INCL_DOSPROCESS
52#define INCL_NOPMAPI
53#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000054#if defined(PYCC_GCC)
55#include <ctype.h>
56#include <io.h>
57#include <stdio.h>
58#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000059#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000060#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000061#endif
62
Thomas Wouters0e3f5912006-08-11 14:57:12 +000063#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000064#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000065#endif /* HAVE_SYS_TYPES_H */
66
67#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000068#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000069#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000070
Guido van Rossum36bc6801995-06-14 22:54:23 +000071#ifdef HAVE_SYS_WAIT_H
72#include <sys/wait.h> /* For WNOHANG */
73#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000074
Thomas Wouters0e3f5912006-08-11 14:57:12 +000075#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000076#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000077#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000078
Guido van Rossumb6775db1994-08-01 11:34:53 +000079#ifdef HAVE_FCNTL_H
80#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000081#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000082
Guido van Rossuma6535fd2001-10-18 19:44:10 +000083#ifdef HAVE_GRP_H
84#include <grp.h>
85#endif
86
Barry Warsaw5676bd12003-01-07 20:57:09 +000087#ifdef HAVE_SYSEXITS_H
88#include <sysexits.h>
89#endif /* HAVE_SYSEXITS_H */
90
Anthony Baxter8a560de2004-10-13 15:30:56 +000091#ifdef HAVE_SYS_LOADAVG_H
92#include <sys/loadavg.h>
93#endif
94
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000095#ifdef HAVE_LANGINFO_H
96#include <langinfo.h>
97#endif
98
Guido van Rossuma4916fa1996-05-23 22:58:55 +000099/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000100/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000101#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000102#include <process.h>
103#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000104#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000105#define HAVE_GETCWD 1
106#define HAVE_OPENDIR 1
107#define HAVE_SYSTEM 1
108#if defined(__OS2__)
109#define HAVE_EXECV 1
110#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000111#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000112#include <process.h>
113#else
114#ifdef __BORLANDC__ /* Borland compiler */
115#define HAVE_EXECV 1
116#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000117#define HAVE_OPENDIR 1
118#define HAVE_PIPE 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000119#define HAVE_SYSTEM 1
120#define HAVE_WAIT 1
121#else
122#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000123#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +0000124#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000125#define HAVE_EXECV 1
126#define HAVE_PIPE 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000127#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +0000128#define HAVE_CWAIT 1
Tim Peters11b23062003-04-23 02:39:17 +0000129#define HAVE_FSYNC 1
130#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000131#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000132#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
133/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000134#else /* all other compilers */
135/* Unix functions that the configure script doesn't check for */
136#define HAVE_EXECV 1
137#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000138#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
139#define HAVE_FORK1 1
140#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000141#define HAVE_GETCWD 1
142#define HAVE_GETEGID 1
143#define HAVE_GETEUID 1
144#define HAVE_GETGID 1
145#define HAVE_GETPPID 1
146#define HAVE_GETUID 1
147#define HAVE_KILL 1
148#define HAVE_OPENDIR 1
149#define HAVE_PIPE 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000150#define HAVE_SYSTEM 1
151#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000152#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000153#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000154#endif /* _MSC_VER */
155#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000156#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000157#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000158
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000159#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000160
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000161#if defined(__sgi)&&_COMPILER_VERSION>=700
162/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
163 (default) */
164extern char *ctermid_r(char *);
165#endif
166
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000167#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000168#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000169extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000170#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000171#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000172extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000173#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000174extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000175#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000176#endif
177#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000178extern int chdir(char *);
179extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000180#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000181extern int chdir(const char *);
182extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000183#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000184#ifdef __BORLANDC__
185extern int chmod(const char *, int);
186#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000187extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000188#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000189/*#ifdef HAVE_FCHMOD
190extern int fchmod(int, mode_t);
191#endif*/
192/*#ifdef HAVE_LCHMOD
193extern int lchmod(const char *, mode_t);
194#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000195extern int chown(const char *, uid_t, gid_t);
196extern char *getcwd(char *, int);
197extern char *strerror(int);
198extern int link(const char *, const char *);
199extern int rename(const char *, const char *);
200extern int stat(const char *, struct stat *);
201extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000202#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000203extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000204#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000206extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000207#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000209
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000210#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000211
Guido van Rossumb6775db1994-08-01 11:34:53 +0000212#ifdef HAVE_UTIME_H
213#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000214#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000215
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000216#ifdef HAVE_SYS_UTIME_H
217#include <sys/utime.h>
218#define HAVE_UTIME_H /* pretend we do for the rest of this file */
219#endif /* HAVE_SYS_UTIME_H */
220
Guido van Rossumb6775db1994-08-01 11:34:53 +0000221#ifdef HAVE_SYS_TIMES_H
222#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000223#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224
225#ifdef HAVE_SYS_PARAM_H
226#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000227#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000228
229#ifdef HAVE_SYS_UTSNAME_H
230#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000231#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000233#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000235#define NAMLEN(dirent) strlen((dirent)->d_name)
236#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000237#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000238#include <direct.h>
239#define NAMLEN(dirent) strlen((dirent)->d_name)
240#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000242#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000243#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000244#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000246#endif
247#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000248#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000249#endif
250#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000252#endif
253#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000255#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000256#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000258#endif
259#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000261#endif
262#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000264#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000265#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000266#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000267#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000268#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000269#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000270
Guido van Rossumd48f2521997-12-05 22:19:34 +0000271#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000272#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000273#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000274
Tim Petersbc2e10e2002-03-03 23:17:02 +0000275#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000276#if defined(PATH_MAX) && PATH_MAX > 1024
277#define MAXPATHLEN PATH_MAX
278#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000279#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000280#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000281#endif /* MAXPATHLEN */
282
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000283#ifdef UNION_WAIT
284/* Emulate some macros on systems that have a union instead of macros */
285
286#ifndef WIFEXITED
287#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
288#endif
289
290#ifndef WEXITSTATUS
291#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
292#endif
293
294#ifndef WTERMSIG
295#define WTERMSIG(u_wait) ((u_wait).w_termsig)
296#endif
297
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000298#define WAIT_TYPE union wait
299#define WAIT_STATUS_INT(s) (s.w_status)
300
301#else /* !UNION_WAIT */
302#define WAIT_TYPE int
303#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000304#endif /* UNION_WAIT */
305
Antoine Pitrouc3ee1662009-05-23 16:02:33 +0000306/* Issue #1983: pid_t can be longer than a C long on some systems */
Antoine Pitrou7852c422009-05-24 11:58:35 +0000307#if !defined(SIZEOF_PID_T) || SIZEOF_PID_T == SIZEOF_INT
Antoine Pitrouc3ee1662009-05-23 16:02:33 +0000308#define PARSE_PID "i"
309#define PyLong_FromPid PyLong_FromLong
310#define PyLong_AsPid PyLong_AsLong
311#elif SIZEOF_PID_T == SIZEOF_LONG
312#define PARSE_PID "l"
313#define PyLong_FromPid PyLong_FromLong
314#define PyLong_AsPid PyLong_AsLong
315#elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG
316#define PARSE_PID "L"
317#define PyLong_FromPid PyLong_FromLongLong
318#define PyLong_AsPid PyLong_AsLongLong
319#else
320#error "sizeof(pid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)"
Antoine Pitrouc3ee1662009-05-23 16:02:33 +0000321#endif /* SIZEOF_PID_T */
322
Greg Wardb48bc172000-03-01 21:51:56 +0000323/* Don't use the "_r" form if we don't need it (also, won't have a
324 prototype for it, at least on Solaris -- maybe others as well?). */
325#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
326#define USE_CTERMID_R
327#endif
328
Fred Drake699f3522000-06-29 21:12:41 +0000329/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000330#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000331#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwis14694662006-02-03 12:54:16 +0000332# define STAT win32_stat
333# define FSTAT win32_fstat
334# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000335#else
336# define STAT stat
337# define FSTAT fstat
338# define STRUCT_STAT struct stat
339#endif
340
Tim Peters11b23062003-04-23 02:39:17 +0000341#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000342#include <sys/mkdev.h>
343#else
344#if defined(MAJOR_IN_SYSMACROS)
345#include <sys/sysmacros.h>
346#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000347#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
348#include <sys/mkdev.h>
349#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000350#endif
Fred Drake699f3522000-06-29 21:12:41 +0000351
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000352#if defined _MSC_VER && _MSC_VER >= 1400
353/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
354 * valid and throw an assertion if it isn't.
355 * Normally, an invalid fd is likely to be a C program error and therefore
356 * an assertion can be useful, but it does contradict the POSIX standard
357 * which for write(2) states:
358 * "Otherwise, -1 shall be returned and errno set to indicate the error."
359 * "[EBADF] The fildes argument is not a valid file descriptor open for
360 * writing."
361 * Furthermore, python allows the user to enter any old integer
362 * as a fd and should merely raise a python exception on error.
363 * The Microsoft CRT doesn't provide an official way to check for the
364 * validity of a file descriptor, but we can emulate its internal behaviour
365 * by using the exported __pinfo data member and knowledge of the
366 * internal structures involved.
367 * The structures below must be updated for each version of visual studio
368 * according to the file internal.h in the CRT source, until MS comes
369 * up with a less hacky way to do this.
370 * (all of this is to avoid globally modifying the CRT behaviour using
371 * _set_invalid_parameter_handler() and _CrtSetReportMode())
372 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000373/* The actual size of the structure is determined at runtime.
374 * Only the first items must be present.
375 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000376typedef struct {
377 intptr_t osfhnd;
378 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000379} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000380
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000381extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000382#define IOINFO_L2E 5
383#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
384#define IOINFO_ARRAYS 64
385#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
386#define FOPEN 0x01
387#define _NO_CONSOLE_FILENO (intptr_t)-2
388
389/* This function emulates what the windows CRT does to validate file handles */
390int
391_PyVerify_fd(int fd)
392{
393 const int i1 = fd >> IOINFO_L2E;
394 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000395
396 static int sizeof_ioinfo = 0;
397
398 /* Determine the actual size of the ioinfo structure,
399 * as used by the CRT loaded in memory
400 */
401 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
402 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
403 }
404 if (sizeof_ioinfo == 0) {
405 /* This should not happen... */
406 goto fail;
407 }
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000408
409 /* See that it isn't a special CLEAR fileno */
410 if (fd != _NO_CONSOLE_FILENO) {
411 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
412 * we check pointer validity and other info
413 */
414 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
415 /* finally, check that the file is open */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000416 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
417 if (info->osfile & FOPEN) {
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000418 return 1;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000419 }
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000420 }
421 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000422 fail:
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000423 errno = EBADF;
424 return 0;
425}
426
427/* the special case of checking dup2. The target fd must be in a sensible range */
428static int
429_PyVerify_fd_dup2(int fd1, int fd2)
430{
431 if (!_PyVerify_fd(fd1))
432 return 0;
433 if (fd2 == _NO_CONSOLE_FILENO)
434 return 0;
435 if ((unsigned)fd2 < _NHANDLE_)
436 return 1;
437 else
438 return 0;
439}
440#else
441/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
442#define _PyVerify_fd_dup2(A, B) (1)
443#endif
444
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000445/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000446#ifdef WITH_NEXT_FRAMEWORK
447/* On Darwin/MacOSX a shared library or framework has no access to
448** environ directly, we must obtain it with _NSGetEnviron().
449*/
450#include <crt_externs.h>
451static char **environ;
452#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000453extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000454#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000455
Barry Warsaw53699e91996-12-10 23:23:01 +0000456static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000457convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000458{
Barry Warsaw53699e91996-12-10 23:23:01 +0000459 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000460#ifdef MS_WINDOWS
461 wchar_t **e;
462#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000463 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000464#endif
Barry Warsaw53699e91996-12-10 23:23:01 +0000465 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000466 if (d == NULL)
467 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000468#ifdef WITH_NEXT_FRAMEWORK
469 if (environ == NULL)
470 environ = *_NSGetEnviron();
471#endif
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000472#ifdef MS_WINDOWS
473 /* _wenviron must be initialized in this way if the program is started
474 through main() instead of wmain(). */
475 _wgetenv(L"");
476 if (_wenviron == NULL)
477 return d;
478 /* This part ignores errors */
479 for (e = _wenviron; *e != NULL; e++) {
480 PyObject *k;
481 PyObject *v;
482 wchar_t *p = wcschr(*e, L'=');
483 if (p == NULL)
484 continue;
485 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
486 if (k == NULL) {
487 PyErr_Clear();
488 continue;
489 }
490 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
491 if (v == NULL) {
492 PyErr_Clear();
493 Py_DECREF(k);
494 continue;
495 }
496 if (PyDict_GetItem(d, k) == NULL) {
497 if (PyDict_SetItem(d, k, v) != 0)
498 PyErr_Clear();
499 }
500 Py_DECREF(k);
501 Py_DECREF(v);
502 }
503#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000504 if (environ == NULL)
505 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000506 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000507 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000508 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000509 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000510 char *p = strchr(*e, '=');
511 if (p == NULL)
512 continue;
Martin v. Löwis011e8422009-05-05 04:43:17 +0000513 k = PyUnicode_Decode(*e, (int)(p-*e),
Martin v. Löwis43c57782009-05-10 08:15:24 +0000514 Py_FileSystemDefaultEncoding, "surrogateescape");
Guido van Rossum6a619f41999-08-03 19:41:10 +0000515 if (k == NULL) {
516 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000517 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000518 }
Martin v. Löwis011e8422009-05-05 04:43:17 +0000519 v = PyUnicode_Decode(p+1, strlen(p+1),
Martin v. Löwis43c57782009-05-10 08:15:24 +0000520 Py_FileSystemDefaultEncoding, "surrogateescape");
Guido van Rossum6a619f41999-08-03 19:41:10 +0000521 if (v == NULL) {
522 PyErr_Clear();
523 Py_DECREF(k);
524 continue;
525 }
526 if (PyDict_GetItem(d, k) == NULL) {
527 if (PyDict_SetItem(d, k, v) != 0)
528 PyErr_Clear();
529 }
530 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000531 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000532 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000533#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000534#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000535 {
536 APIRET rc;
537 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
538
539 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000540 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Christian Heimes72b710a2008-05-26 13:28:38 +0000541 PyObject *v = PyBytes_FromString(buffer);
Neal Norwitz93c56822007-08-26 07:10:06 +0000542 PyDict_SetItemString(d, "BEGINLIBPATH", v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000543 Py_DECREF(v);
544 }
545 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
546 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
Christian Heimes72b710a2008-05-26 13:28:38 +0000547 PyObject *v = PyBytes_FromString(buffer);
Neal Norwitz93c56822007-08-26 07:10:06 +0000548 PyDict_SetItemString(d, "ENDLIBPATH", v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000549 Py_DECREF(v);
550 }
551 }
552#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000553 return d;
554}
555
Martin v. Löwis011e8422009-05-05 04:43:17 +0000556/* Convert a bytes object to a char*. Optionally lock the buffer if it is a
557 bytes array. */
558
559static char*
560bytes2str(PyObject* o, int lock)
561{
562 if(PyBytes_Check(o))
563 return PyBytes_AsString(o);
564 else if(PyByteArray_Check(o)) {
565 if (lock && PyObject_GetBuffer(o, NULL, 0) < 0)
566 /* On a bytearray, this should not fail. */
567 PyErr_BadInternalCall();
568 return PyByteArray_AsString(o);
569 } else {
570 /* The FS converter should have verified that this
571 is either bytes or bytearray. */
572 Py_FatalError("bad object passed to bytes2str");
573 /* not reached. */
574 return "";
575 }
576}
577
578/* Release the lock, decref the object. */
579static void
580release_bytes(PyObject* o)
581{
582 if (PyByteArray_Check(o))
583 o->ob_type->tp_as_buffer->bf_releasebuffer(NULL, 0);
584 Py_DECREF(o);
585}
586
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000587
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000588/* Set a POSIX-specific error from errno, and return NULL */
589
Barry Warsawd58d7641998-07-23 16:14:40 +0000590static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000591posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000592{
Barry Warsawca74da41999-02-09 19:31:45 +0000593 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000594}
Barry Warsawd58d7641998-07-23 16:14:40 +0000595static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000596posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000597{
Barry Warsawca74da41999-02-09 19:31:45 +0000598 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000599}
600
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000601#ifdef MS_WINDOWS
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000602static PyObject *
603posix_error_with_unicode_filename(Py_UNICODE* name)
604{
605 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
606}
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000607#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000608
609
Mark Hammondef8b6542001-05-13 08:04:26 +0000610static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +0000611posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +0000612{
Martin v. Löwis011e8422009-05-05 04:43:17 +0000613 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError,
614 bytes2str(name, 0));
615 release_bytes(name);
Mark Hammondef8b6542001-05-13 08:04:26 +0000616 return rc;
617}
618
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000619#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000620static PyObject *
621win32_error(char* function, char* filename)
622{
Mark Hammond33a6da92000-08-15 00:46:38 +0000623 /* XXX We should pass the function name along in the future.
Georg Brandl38feaf02008-05-25 07:45:51 +0000624 (winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000625 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000626 Windows error object, which is non-trivial.
627 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000628 errno = GetLastError();
629 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000630 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000631 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000632 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000633}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000634
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000635static PyObject *
636win32_error_unicode(char* function, Py_UNICODE* filename)
637{
638 /* XXX - see win32_error for comments on 'function' */
639 errno = GetLastError();
640 if (filename)
641 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
642 else
643 return PyErr_SetFromWindowsErr(errno);
644}
645
Thomas Wouters477c8d52006-05-27 19:21:47 +0000646static int
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000647convert_to_unicode(PyObject **param)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000648{
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000649 if (PyUnicode_CheckExact(*param))
650 Py_INCREF(*param);
651 else if (PyUnicode_Check(*param))
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000652 /* For a Unicode subtype that's not a Unicode object,
653 return a true Unicode object with the same data. */
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000654 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
655 PyUnicode_GET_SIZE(*param));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000656 else
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000657 *param = PyUnicode_FromEncodedObject(*param,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000658 Py_FileSystemDefaultEncoding,
659 "strict");
660 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000661}
662
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000663#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000664
Guido van Rossumd48f2521997-12-05 22:19:34 +0000665#if defined(PYOS_OS2)
666/**********************************************************************
667 * Helper Function to Trim and Format OS/2 Messages
668 **********************************************************************/
669 static void
670os2_formatmsg(char *msgbuf, int msglen, char *reason)
671{
672 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
673
674 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
675 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
676
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000677 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000678 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
679 }
680
681 /* Add Optional Reason Text */
682 if (reason) {
683 strcat(msgbuf, " : ");
684 strcat(msgbuf, reason);
685 }
686}
687
688/**********************************************************************
689 * Decode an OS/2 Operating System Error Code
690 *
691 * A convenience function to lookup an OS/2 error code and return a
692 * text message we can use to raise a Python exception.
693 *
694 * Notes:
695 * The messages for errors returned from the OS/2 kernel reside in
696 * the file OSO001.MSG in the \OS2 directory hierarchy.
697 *
698 **********************************************************************/
699 static char *
700os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
701{
702 APIRET rc;
703 ULONG msglen;
704
705 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
706 Py_BEGIN_ALLOW_THREADS
707 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
708 errorcode, "oso001.msg", &msglen);
709 Py_END_ALLOW_THREADS
710
711 if (rc == NO_ERROR)
712 os2_formatmsg(msgbuf, msglen, reason);
713 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000714 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000715 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000716
717 return msgbuf;
718}
719
720/* Set an OS/2-specific error and return NULL. OS/2 kernel
721 errors are not in a global variable e.g. 'errno' nor are
722 they congruent with posix error numbers. */
723
724static PyObject * os2_error(int code)
725{
726 char text[1024];
727 PyObject *v;
728
729 os2_strerror(text, sizeof(text), code, "");
730
731 v = Py_BuildValue("(is)", code, text);
732 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000733 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000734 Py_DECREF(v);
735 }
736 return NULL; /* Signal to Python that an Exception is Pending */
737}
738
739#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000740
741/* POSIX generic methods */
742
Barry Warsaw53699e91996-12-10 23:23:01 +0000743static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000744posix_fildes(PyObject *fdobj, int (*func)(int))
745{
746 int fd;
747 int res;
748 fd = PyObject_AsFileDescriptor(fdobj);
749 if (fd < 0)
750 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000751 if (!_PyVerify_fd(fd))
752 return posix_error();
Fred Drake4d1e64b2002-04-15 19:40:07 +0000753 Py_BEGIN_ALLOW_THREADS
754 res = (*func)(fd);
755 Py_END_ALLOW_THREADS
756 if (res < 0)
757 return posix_error();
758 Py_INCREF(Py_None);
759 return Py_None;
760}
Guido van Rossum21142a01999-01-08 21:05:37 +0000761
762static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000763posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000764{
Martin v. Löwis011e8422009-05-05 04:43:17 +0000765 PyObject *opath1 = NULL;
766 char *path1;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000767 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000768 if (!PyArg_ParseTuple(args, format,
Martin v. Löwis011e8422009-05-05 04:43:17 +0000769 PyUnicode_FSConverter, &opath1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000770 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +0000771 path1 = bytes2str(opath1, 1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000772 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000773 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000774 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000775 if (res < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +0000776 return posix_error_with_allocated_filename(opath1);
777 release_bytes(opath1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000778 Py_INCREF(Py_None);
779 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000780}
781
Barry Warsaw53699e91996-12-10 23:23:01 +0000782static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000783posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000784 char *format,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000785 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000786{
Antoine Pitroua6bb9842009-05-10 22:27:00 +0000787 PyObject *opath1 = NULL, *opath2 = NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +0000788 char *path1, *path2;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000789 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000790 if (!PyArg_ParseTuple(args, format,
Martin v. Löwis011e8422009-05-05 04:43:17 +0000791 PyUnicode_FSConverter, &opath1,
Antoine Pitroua6bb9842009-05-10 22:27:00 +0000792 PyUnicode_FSConverter, &opath2)) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000793 return NULL;
Antoine Pitroua6bb9842009-05-10 22:27:00 +0000794 }
Martin v. Löwis011e8422009-05-05 04:43:17 +0000795 path1 = bytes2str(opath1, 1);
796 path2 = bytes2str(opath2, 1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000797 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000798 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000799 Py_END_ALLOW_THREADS
Martin v. Löwis011e8422009-05-05 04:43:17 +0000800 release_bytes(opath1);
801 release_bytes(opath2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000802 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000803 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000804 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000805 Py_INCREF(Py_None);
806 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000807}
808
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000809#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +0000810static PyObject*
811win32_1str(PyObject* args, char* func,
812 char* format, BOOL (__stdcall *funcA)(LPCSTR),
813 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
814{
815 PyObject *uni;
816 char *ansi;
817 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +0000818
819 if (!PyArg_ParseTuple(args, wformat, &uni))
820 PyErr_Clear();
821 else {
822 Py_BEGIN_ALLOW_THREADS
823 result = funcW(PyUnicode_AsUnicode(uni));
824 Py_END_ALLOW_THREADS
825 if (!result)
826 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
827 Py_INCREF(Py_None);
828 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000829 }
830 if (!PyArg_ParseTuple(args, format, &ansi))
831 return NULL;
832 Py_BEGIN_ALLOW_THREADS
833 result = funcA(ansi);
834 Py_END_ALLOW_THREADS
835 if (!result)
836 return win32_error(func, ansi);
837 Py_INCREF(Py_None);
838 return Py_None;
839
840}
841
842/* This is a reimplementation of the C library's chdir function,
843 but one that produces Win32 errors instead of DOS error codes.
844 chdir is essentially a wrapper around SetCurrentDirectory; however,
845 it also needs to set "magic" environment variables indicating
846 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000847static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000848win32_chdir(LPCSTR path)
849{
850 char new_path[MAX_PATH+1];
851 int result;
852 char env[4] = "=x:";
853
854 if(!SetCurrentDirectoryA(path))
855 return FALSE;
856 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
857 if (!result)
858 return FALSE;
859 /* In the ANSI API, there should not be any paths longer
860 than MAX_PATH. */
861 assert(result <= MAX_PATH+1);
862 if (strncmp(new_path, "\\\\", 2) == 0 ||
863 strncmp(new_path, "//", 2) == 0)
864 /* UNC path, nothing to do. */
865 return TRUE;
866 env[1] = new_path[0];
867 return SetEnvironmentVariableA(env, new_path);
868}
869
870/* The Unicode version differs from the ANSI version
871 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000872static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000873win32_wchdir(LPCWSTR path)
874{
875 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
876 int result;
877 wchar_t env[4] = L"=x:";
878
879 if(!SetCurrentDirectoryW(path))
880 return FALSE;
881 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
882 if (!result)
883 return FALSE;
884 if (result > MAX_PATH+1) {
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000885 new_path = malloc(result * sizeof(wchar_t));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000886 if (!new_path) {
887 SetLastError(ERROR_OUTOFMEMORY);
888 return FALSE;
889 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000890 result = GetCurrentDirectoryW(result, new_path);
891 if (!result) {
892 free(new_path);
893 return FALSE;
894 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000895 }
896 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
897 wcsncmp(new_path, L"//", 2) == 0)
898 /* UNC path, nothing to do. */
899 return TRUE;
900 env[1] = new_path[0];
901 result = SetEnvironmentVariableW(env, new_path);
902 if (new_path != _new_path)
903 free(new_path);
904 return result;
905}
906#endif
907
Martin v. Löwis14694662006-02-03 12:54:16 +0000908#ifdef MS_WINDOWS
909/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
910 - time stamps are restricted to second resolution
911 - file modification times suffer from forth-and-back conversions between
912 UTC and local time
913 Therefore, we implement our own stat, based on the Win32 API directly.
914*/
915#define HAVE_STAT_NSEC 1
916
917struct win32_stat{
918 int st_dev;
919 __int64 st_ino;
920 unsigned short st_mode;
921 int st_nlink;
922 int st_uid;
923 int st_gid;
924 int st_rdev;
925 __int64 st_size;
926 int st_atime;
927 int st_atime_nsec;
928 int st_mtime;
929 int st_mtime_nsec;
930 int st_ctime;
931 int st_ctime_nsec;
932};
933
934static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
935
936static void
937FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
938{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000939 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
940 /* Cannot simply cast and dereference in_ptr,
941 since it might not be aligned properly */
942 __int64 in;
943 memcpy(&in, in_ptr, sizeof(in));
Martin v. Löwis14694662006-02-03 12:54:16 +0000944 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
945 /* XXX Win32 supports time stamps past 2038; we currently don't */
946 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
947}
948
Thomas Wouters477c8d52006-05-27 19:21:47 +0000949static void
950time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
951{
952 /* XXX endianness */
953 __int64 out;
954 out = time_in + secs_between_epochs;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000955 out = out * 10000000 + nsec_in / 100;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000956 memcpy(out_ptr, &out, sizeof(out));
957}
958
Martin v. Löwis14694662006-02-03 12:54:16 +0000959/* Below, we *know* that ugo+r is 0444 */
960#if _S_IREAD != 0400
961#error Unsupported C library
962#endif
963static int
964attributes_to_mode(DWORD attr)
965{
966 int m = 0;
967 if (attr & FILE_ATTRIBUTE_DIRECTORY)
968 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
969 else
970 m |= _S_IFREG;
971 if (attr & FILE_ATTRIBUTE_READONLY)
972 m |= 0444;
973 else
974 m |= 0666;
975 return m;
976}
977
978static int
979attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
980{
981 memset(result, 0, sizeof(*result));
982 result->st_mode = attributes_to_mode(info->dwFileAttributes);
983 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
984 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
985 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
986 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
987
988 return 0;
989}
990
Guido van Rossumd8faa362007-04-27 19:54:29 +0000991static BOOL
992attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
993{
994 HANDLE hFindFile;
995 WIN32_FIND_DATAA FileData;
996 hFindFile = FindFirstFileA(pszFile, &FileData);
997 if (hFindFile == INVALID_HANDLE_VALUE)
998 return FALSE;
999 FindClose(hFindFile);
1000 pfad->dwFileAttributes = FileData.dwFileAttributes;
1001 pfad->ftCreationTime = FileData.ftCreationTime;
1002 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
1003 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
1004 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
1005 pfad->nFileSizeLow = FileData.nFileSizeLow;
1006 return TRUE;
1007}
1008
1009static BOOL
1010attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
1011{
1012 HANDLE hFindFile;
1013 WIN32_FIND_DATAW FileData;
1014 hFindFile = FindFirstFileW(pszFile, &FileData);
1015 if (hFindFile == INVALID_HANDLE_VALUE)
1016 return FALSE;
1017 FindClose(hFindFile);
1018 pfad->dwFileAttributes = FileData.dwFileAttributes;
1019 pfad->ftCreationTime = FileData.ftCreationTime;
1020 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
1021 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
1022 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
1023 pfad->nFileSizeLow = FileData.nFileSizeLow;
1024 return TRUE;
1025}
1026
Thomas Wouters89f507f2006-12-13 04:49:30 +00001027static BOOL WINAPI
1028Py_GetFileAttributesExA(LPCSTR pszFile,
1029 GET_FILEEX_INFO_LEVELS level,
1030 LPVOID pv)
1031{
1032 BOOL result;
Thomas Wouters89f507f2006-12-13 04:49:30 +00001033 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
1034 /* First try to use the system's implementation, if that is
1035 available and either succeeds to gives an error other than
1036 that it isn't implemented. */
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001037 result = GetFileAttributesExA(pszFile, level, pv);
1038 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
1039 return result;
Thomas Wouters89f507f2006-12-13 04:49:30 +00001040 /* It's either not present, or not implemented.
1041 Emulate using FindFirstFile. */
1042 if (level != GetFileExInfoStandard) {
1043 SetLastError(ERROR_INVALID_PARAMETER);
1044 return FALSE;
1045 }
1046 /* Use GetFileAttributes to validate that the file name
1047 does not contain wildcards (which FindFirstFile would
1048 accept). */
1049 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
1050 return FALSE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001051 return attributes_from_dir(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +00001052}
1053
1054static BOOL WINAPI
1055Py_GetFileAttributesExW(LPCWSTR pszFile,
1056 GET_FILEEX_INFO_LEVELS level,
1057 LPVOID pv)
1058{
1059 BOOL result;
Thomas Wouters89f507f2006-12-13 04:49:30 +00001060 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
1061 /* First try to use the system's implementation, if that is
1062 available and either succeeds to gives an error other than
1063 that it isn't implemented. */
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001064 result = GetFileAttributesExW(pszFile, level, pv);
1065 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
1066 return result;
Thomas Wouters89f507f2006-12-13 04:49:30 +00001067 /* It's either not present, or not implemented.
1068 Emulate using FindFirstFile. */
1069 if (level != GetFileExInfoStandard) {
1070 SetLastError(ERROR_INVALID_PARAMETER);
1071 return FALSE;
1072 }
1073 /* Use GetFileAttributes to validate that the file name
1074 does not contain wildcards (which FindFirstFile would
1075 accept). */
1076 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
1077 return FALSE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001078 return attributes_from_dir_w(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +00001079}
1080
Martin v. Löwis14694662006-02-03 12:54:16 +00001081static int
1082win32_stat(const char* path, struct win32_stat *result)
1083{
1084 WIN32_FILE_ATTRIBUTE_DATA info;
1085 int code;
1086 char *dot;
1087 /* XXX not supported on Win95 and NT 3.x */
Thomas Wouters89f507f2006-12-13 04:49:30 +00001088 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
Guido van Rossumd8faa362007-04-27 19:54:29 +00001089 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1090 /* Protocol violation: we explicitly clear errno, instead of
1091 setting it to a POSIX error. Callers should use GetLastError. */
1092 errno = 0;
1093 return -1;
1094 } else {
1095 /* Could not get attributes on open file. Fall back to
1096 reading the directory. */
1097 if (!attributes_from_dir(path, &info)) {
1098 /* Very strange. This should not fail now */
1099 errno = 0;
1100 return -1;
1101 }
1102 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001103 }
1104 code = attribute_data_to_stat(&info, result);
1105 if (code != 0)
1106 return code;
1107 /* Set S_IFEXEC if it is an .exe, .bat, ... */
1108 dot = strrchr(path, '.');
1109 if (dot) {
1110 if (stricmp(dot, ".bat") == 0 ||
1111 stricmp(dot, ".cmd") == 0 ||
1112 stricmp(dot, ".exe") == 0 ||
1113 stricmp(dot, ".com") == 0)
1114 result->st_mode |= 0111;
1115 }
1116 return code;
1117}
1118
1119static int
1120win32_wstat(const wchar_t* path, struct win32_stat *result)
1121{
1122 int code;
1123 const wchar_t *dot;
1124 WIN32_FILE_ATTRIBUTE_DATA info;
1125 /* XXX not supported on Win95 and NT 3.x */
Thomas Wouters89f507f2006-12-13 04:49:30 +00001126 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
Guido van Rossumd8faa362007-04-27 19:54:29 +00001127 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1128 /* Protocol violation: we explicitly clear errno, instead of
1129 setting it to a POSIX error. Callers should use GetLastError. */
1130 errno = 0;
1131 return -1;
1132 } else {
1133 /* Could not get attributes on open file. Fall back to
1134 reading the directory. */
1135 if (!attributes_from_dir_w(path, &info)) {
1136 /* Very strange. This should not fail now */
1137 errno = 0;
1138 return -1;
1139 }
1140 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001141 }
1142 code = attribute_data_to_stat(&info, result);
1143 if (code < 0)
1144 return code;
1145 /* Set IFEXEC if it is an .exe, .bat, ... */
1146 dot = wcsrchr(path, '.');
1147 if (dot) {
1148 if (_wcsicmp(dot, L".bat") == 0 ||
1149 _wcsicmp(dot, L".cmd") == 0 ||
1150 _wcsicmp(dot, L".exe") == 0 ||
1151 _wcsicmp(dot, L".com") == 0)
1152 result->st_mode |= 0111;
1153 }
1154 return code;
1155}
1156
1157static int
1158win32_fstat(int file_number, struct win32_stat *result)
1159{
1160 BY_HANDLE_FILE_INFORMATION info;
1161 HANDLE h;
1162 int type;
1163
1164 h = (HANDLE)_get_osfhandle(file_number);
1165
1166 /* Protocol violation: we explicitly clear errno, instead of
1167 setting it to a POSIX error. Callers should use GetLastError. */
1168 errno = 0;
1169
1170 if (h == INVALID_HANDLE_VALUE) {
1171 /* This is really a C library error (invalid file handle).
1172 We set the Win32 error to the closes one matching. */
1173 SetLastError(ERROR_INVALID_HANDLE);
1174 return -1;
1175 }
1176 memset(result, 0, sizeof(*result));
1177
1178 type = GetFileType(h);
1179 if (type == FILE_TYPE_UNKNOWN) {
1180 DWORD error = GetLastError();
1181 if (error != 0) {
1182 return -1;
1183 }
1184 /* else: valid but unknown file */
1185 }
1186
1187 if (type != FILE_TYPE_DISK) {
1188 if (type == FILE_TYPE_CHAR)
1189 result->st_mode = _S_IFCHR;
1190 else if (type == FILE_TYPE_PIPE)
1191 result->st_mode = _S_IFIFO;
1192 return 0;
1193 }
1194
1195 if (!GetFileInformationByHandle(h, &info)) {
1196 return -1;
1197 }
1198
1199 /* similar to stat() */
1200 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1201 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1202 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1203 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1204 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1205 /* specific to fstat() */
1206 result->st_nlink = info.nNumberOfLinks;
1207 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1208 return 0;
1209}
1210
1211#endif /* MS_WINDOWS */
1212
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001213PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001214"stat_result: Result from stat or lstat.\n\n\
1215This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001216 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001217or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1218\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001219Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1220or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001221\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001222See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001223
1224static PyStructSequence_Field stat_result_fields[] = {
1225 {"st_mode", "protection bits"},
1226 {"st_ino", "inode"},
1227 {"st_dev", "device"},
1228 {"st_nlink", "number of hard links"},
1229 {"st_uid", "user ID of owner"},
1230 {"st_gid", "group ID of owner"},
1231 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001232 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1233 {NULL, "integer time of last access"},
1234 {NULL, "integer time of last modification"},
1235 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001236 {"st_atime", "time of last access"},
1237 {"st_mtime", "time of last modification"},
1238 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001239#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001240 {"st_blksize", "blocksize for filesystem I/O"},
1241#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001242#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001243 {"st_blocks", "number of blocks allocated"},
1244#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001245#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001246 {"st_rdev", "device type (if inode device)"},
1247#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001248#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1249 {"st_flags", "user defined flags for file"},
1250#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001251#ifdef HAVE_STRUCT_STAT_ST_GEN
1252 {"st_gen", "generation number"},
1253#endif
1254#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1255 {"st_birthtime", "time of creation"},
1256#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001257 {0}
1258};
1259
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001260#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001261#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001262#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001263#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001264#endif
1265
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001266#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001267#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1268#else
1269#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1270#endif
1271
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001272#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001273#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1274#else
1275#define ST_RDEV_IDX ST_BLOCKS_IDX
1276#endif
1277
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001278#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1279#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1280#else
1281#define ST_FLAGS_IDX ST_RDEV_IDX
1282#endif
1283
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001284#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001285#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001286#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001287#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001288#endif
1289
1290#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1291#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1292#else
1293#define ST_BIRTHTIME_IDX ST_GEN_IDX
1294#endif
1295
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001296static PyStructSequence_Desc stat_result_desc = {
1297 "stat_result", /* name */
1298 stat_result__doc__, /* doc */
1299 stat_result_fields,
1300 10
1301};
1302
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001303PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001304"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1305This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001306 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001307or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001308\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001309See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001310
1311static PyStructSequence_Field statvfs_result_fields[] = {
1312 {"f_bsize", },
1313 {"f_frsize", },
1314 {"f_blocks", },
1315 {"f_bfree", },
1316 {"f_bavail", },
1317 {"f_files", },
1318 {"f_ffree", },
1319 {"f_favail", },
1320 {"f_flag", },
1321 {"f_namemax",},
1322 {0}
1323};
1324
1325static PyStructSequence_Desc statvfs_result_desc = {
1326 "statvfs_result", /* name */
1327 statvfs_result__doc__, /* doc */
1328 statvfs_result_fields,
1329 10
1330};
1331
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001332static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001333static PyTypeObject StatResultType;
1334static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001335static newfunc structseq_new;
1336
1337static PyObject *
1338statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1339{
1340 PyStructSequence *result;
1341 int i;
1342
1343 result = (PyStructSequence*)structseq_new(type, args, kwds);
1344 if (!result)
1345 return NULL;
1346 /* If we have been initialized from a tuple,
1347 st_?time might be set to None. Initialize it
1348 from the int slots. */
1349 for (i = 7; i <= 9; i++) {
1350 if (result->ob_item[i+3] == Py_None) {
1351 Py_DECREF(Py_None);
1352 Py_INCREF(result->ob_item[i]);
1353 result->ob_item[i+3] = result->ob_item[i];
1354 }
1355 }
1356 return (PyObject*)result;
1357}
1358
1359
1360
1361/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001362static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001363
1364PyDoc_STRVAR(stat_float_times__doc__,
1365"stat_float_times([newval]) -> oldval\n\n\
1366Determine whether os.[lf]stat represents time stamps as float objects.\n\
1367If newval is True, future calls to stat() return floats, if it is False,\n\
1368future calls return ints. \n\
1369If newval is omitted, return the current setting.\n");
1370
1371static PyObject*
1372stat_float_times(PyObject* self, PyObject *args)
1373{
1374 int newval = -1;
1375 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1376 return NULL;
1377 if (newval == -1)
1378 /* Return old value */
1379 return PyBool_FromLong(_stat_float_times);
1380 _stat_float_times = newval;
1381 Py_INCREF(Py_None);
1382 return Py_None;
1383}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001384
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001385static void
1386fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1387{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001388 PyObject *fval,*ival;
1389#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001390 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001391#else
Christian Heimes217cfd12007-12-02 14:31:20 +00001392 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001393#endif
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001394 if (!ival)
1395 return;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001396 if (_stat_float_times) {
1397 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1398 } else {
1399 fval = ival;
1400 Py_INCREF(fval);
1401 }
1402 PyStructSequence_SET_ITEM(v, index, ival);
1403 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001404}
1405
Tim Peters5aa91602002-01-30 05:46:57 +00001406/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001407 (used by posix_stat() and posix_fstat()) */
1408static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001409_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001410{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001411 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001412 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001413 if (v == NULL)
1414 return NULL;
1415
Christian Heimes217cfd12007-12-02 14:31:20 +00001416 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001417#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001418 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001419 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001420#else
Christian Heimes217cfd12007-12-02 14:31:20 +00001421 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001422#endif
1423#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001424 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001425 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001426#else
Christian Heimes217cfd12007-12-02 14:31:20 +00001427 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001428#endif
Christian Heimes217cfd12007-12-02 14:31:20 +00001429 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1430 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1431 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001432#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001433 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001434 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001435#else
Christian Heimes217cfd12007-12-02 14:31:20 +00001436 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001437#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001438
Martin v. Löwis14694662006-02-03 12:54:16 +00001439#if defined(HAVE_STAT_TV_NSEC)
1440 ansec = st->st_atim.tv_nsec;
1441 mnsec = st->st_mtim.tv_nsec;
1442 cnsec = st->st_ctim.tv_nsec;
1443#elif defined(HAVE_STAT_TV_NSEC2)
1444 ansec = st->st_atimespec.tv_nsec;
1445 mnsec = st->st_mtimespec.tv_nsec;
1446 cnsec = st->st_ctimespec.tv_nsec;
1447#elif defined(HAVE_STAT_NSEC)
1448 ansec = st->st_atime_nsec;
1449 mnsec = st->st_mtime_nsec;
1450 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001451#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001452 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001453#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001454 fill_time(v, 7, st->st_atime, ansec);
1455 fill_time(v, 8, st->st_mtime, mnsec);
1456 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001457
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001458#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001459 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001460 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001461#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001462#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001463 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001464 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001465#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001466#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001467 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001468 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001469#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001470#ifdef HAVE_STRUCT_STAT_ST_GEN
1471 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001472 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001473#endif
1474#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1475 {
1476 PyObject *val;
1477 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001478 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001479#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001480 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001481#else
1482 bnsec = 0;
1483#endif
1484 if (_stat_float_times) {
1485 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1486 } else {
Christian Heimes217cfd12007-12-02 14:31:20 +00001487 val = PyLong_FromLong((long)bsec);
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001488 }
1489 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1490 val);
1491 }
1492#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001493#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1494 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001495 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001496#endif
Fred Drake699f3522000-06-29 21:12:41 +00001497
1498 if (PyErr_Occurred()) {
1499 Py_DECREF(v);
1500 return NULL;
1501 }
1502
1503 return v;
1504}
1505
Martin v. Löwisd8948722004-06-02 09:57:56 +00001506#ifdef MS_WINDOWS
1507
1508/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1509 where / can be used in place of \ and the trailing slash is optional.
1510 Both SERVER and SHARE must have at least one character.
1511*/
1512
1513#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1514#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001515#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001516#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001517#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001518
Tim Peters4ad82172004-08-30 17:02:04 +00001519static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001520IsUNCRootA(char *path, int pathlen)
1521{
1522 #define ISSLASH ISSLASHA
1523
1524 int i, share;
1525
1526 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1527 /* minimum UNCRoot is \\x\y */
1528 return FALSE;
1529 for (i = 2; i < pathlen ; i++)
1530 if (ISSLASH(path[i])) break;
1531 if (i == 2 || i == pathlen)
1532 /* do not allow \\\SHARE or \\SERVER */
1533 return FALSE;
1534 share = i+1;
1535 for (i = share; i < pathlen; i++)
1536 if (ISSLASH(path[i])) break;
1537 return (i != share && (i == pathlen || i == pathlen-1));
1538
1539 #undef ISSLASH
1540}
1541
Tim Peters4ad82172004-08-30 17:02:04 +00001542static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001543IsUNCRootW(Py_UNICODE *path, int pathlen)
1544{
1545 #define ISSLASH ISSLASHW
1546
1547 int i, share;
1548
1549 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1550 /* minimum UNCRoot is \\x\y */
1551 return FALSE;
1552 for (i = 2; i < pathlen ; i++)
1553 if (ISSLASH(path[i])) break;
1554 if (i == 2 || i == pathlen)
1555 /* do not allow \\\SHARE or \\SERVER */
1556 return FALSE;
1557 share = i+1;
1558 for (i = share; i < pathlen; i++)
1559 if (ISSLASH(path[i])) break;
1560 return (i != share && (i == pathlen || i == pathlen-1));
1561
1562 #undef ISSLASH
1563}
Martin v. Löwisd8948722004-06-02 09:57:56 +00001564#endif /* MS_WINDOWS */
1565
Barry Warsaw53699e91996-12-10 23:23:01 +00001566static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001567posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001568 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001569#ifdef __VMS
1570 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1571#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001572 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001573#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001574 char *wformat,
1575 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001576{
Fred Drake699f3522000-06-29 21:12:41 +00001577 STRUCT_STAT st;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001578 PyObject *opath;
1579 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001580 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001581 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001582
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001583#ifdef MS_WINDOWS
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001584 PyUnicodeObject *po;
1585 if (PyArg_ParseTuple(args, wformat, &po)) {
1586 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
Martin v. Löwis14694662006-02-03 12:54:16 +00001587
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001588 Py_BEGIN_ALLOW_THREADS
1589 /* PyUnicode_AS_UNICODE result OK without
1590 thread lock as it is a simple dereference. */
1591 res = wstatfunc(wpath, &st);
1592 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001593
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001594 if (res != 0)
1595 return win32_error_unicode("stat", wpath);
1596 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001597 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001598 /* Drop the argument parsing error as narrow strings
1599 are also valid. */
1600 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001601#endif
1602
Tim Peters5aa91602002-01-30 05:46:57 +00001603 if (!PyArg_ParseTuple(args, format,
Martin v. Löwis011e8422009-05-05 04:43:17 +00001604 PyUnicode_FSConverter, &opath))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001605 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001606 path = bytes2str(opath, 1);
Barry Warsaw53699e91996-12-10 23:23:01 +00001607 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001608 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001609 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001610
1611 if (res != 0) {
1612#ifdef MS_WINDOWS
Martin v. Löwis011e8422009-05-05 04:43:17 +00001613 result = win32_error("stat", path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001614#else
Martin v. Löwis011e8422009-05-05 04:43:17 +00001615 result = posix_error_with_filename(path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001616#endif
1617 }
1618 else
1619 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001620
Martin v. Löwis011e8422009-05-05 04:43:17 +00001621 release_bytes(opath);
Martin v. Löwis14694662006-02-03 12:54:16 +00001622 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001623}
1624
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001625/* POSIX methods */
1626
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001627PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001628"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001629Use the real uid/gid to test for access to a path. Note that most\n\
1630operations will use the effective uid/gid, therefore this routine can\n\
1631be used in a suid/sgid environment to test if the invoking user has the\n\
1632specified access to the path. The mode argument can be F_OK to test\n\
1633existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001634
1635static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001636posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001637{
Martin v. Löwis011e8422009-05-05 04:43:17 +00001638 PyObject *opath;
Guido van Rossum015f22a1999-01-06 22:52:38 +00001639 char *path;
1640 int mode;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001641
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001642#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001643 DWORD attr;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001644 PyUnicodeObject *po;
1645 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1646 Py_BEGIN_ALLOW_THREADS
1647 /* PyUnicode_AS_UNICODE OK without thread lock as
1648 it is a simple dereference. */
1649 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1650 Py_END_ALLOW_THREADS
1651 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001652 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001653 /* Drop the argument parsing error as narrow strings
1654 are also valid. */
1655 PyErr_Clear();
Martin v. Löwis011e8422009-05-05 04:43:17 +00001656 if (!PyArg_ParseTuple(args, "O&i:access",
1657 PyUnicode_FSConverter, &opath, &mode))
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001658 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001659 path = bytes2str(opath, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001660 Py_BEGIN_ALLOW_THREADS
1661 attr = GetFileAttributesA(path);
1662 Py_END_ALLOW_THREADS
Martin v. Löwis011e8422009-05-05 04:43:17 +00001663 release_bytes(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001664finish:
1665 if (attr == 0xFFFFFFFF)
1666 /* File does not exist, or cannot read attributes */
1667 return PyBool_FromLong(0);
1668 /* Access is possible if either write access wasn't requested, or
Guido van Rossumb00324f2007-12-04 01:13:14 +00001669 the file isn't read-only, or if it's a directory, as there are
1670 no read-only directories on Windows. */
1671 return PyBool_FromLong(!(mode & 2)
1672 || !(attr & FILE_ATTRIBUTE_READONLY)
1673 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001674#else
1675 int res;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001676 if (!PyArg_ParseTuple(args, "O&i:access",
1677 PyUnicode_FSConverter, &opath, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001678 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001679 path = bytes2str(opath, 1);
Guido van Rossum015f22a1999-01-06 22:52:38 +00001680 Py_BEGIN_ALLOW_THREADS
1681 res = access(path, mode);
1682 Py_END_ALLOW_THREADS
Martin v. Löwis011e8422009-05-05 04:43:17 +00001683 release_bytes(opath);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001684 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001685#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001686}
1687
Guido van Rossumd371ff11999-01-25 16:12:23 +00001688#ifndef F_OK
1689#define F_OK 0
1690#endif
1691#ifndef R_OK
1692#define R_OK 4
1693#endif
1694#ifndef W_OK
1695#define W_OK 2
1696#endif
1697#ifndef X_OK
1698#define X_OK 1
1699#endif
1700
1701#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001702PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001703"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001704Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001705
1706static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001707posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001708{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001709 int id;
1710 char *ret;
1711
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001712 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001713 return NULL;
1714
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001715#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001716 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001717 if (id == 0) {
1718 ret = ttyname();
1719 }
1720 else {
1721 ret = NULL;
1722 }
1723#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001724 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001725#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001726 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001727 return posix_error();
Neal Norwitz93c56822007-08-26 07:10:06 +00001728 return PyUnicode_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001729}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001730#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001731
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001732#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001733PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001734"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001735Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001736
1737static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001738posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001739{
1740 char *ret;
1741 char buffer[L_ctermid];
1742
Greg Wardb48bc172000-03-01 21:51:56 +00001743#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001744 ret = ctermid_r(buffer);
1745#else
1746 ret = ctermid(buffer);
1747#endif
1748 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001749 return posix_error();
Neal Norwitz93c56822007-08-26 07:10:06 +00001750 return PyUnicode_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001751}
1752#endif
1753
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001754PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001755"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001756Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001757
Barry Warsaw53699e91996-12-10 23:23:01 +00001758static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001759posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001760{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001761#ifdef MS_WINDOWS
Amaury Forgeot d'Arcc72ef8b2008-10-03 18:38:26 +00001762 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001763#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Martin v. Löwis011e8422009-05-05 04:43:17 +00001764 return posix_1str(args, "O&:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001765#elif defined(__VMS)
Martin v. Löwis011e8422009-05-05 04:43:17 +00001766 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001767#else
Martin v. Löwis011e8422009-05-05 04:43:17 +00001768 return posix_1str(args, "O&:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001769#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001770}
1771
Fred Drake4d1e64b2002-04-15 19:40:07 +00001772#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001773PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001774"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001775Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001776opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001777
1778static PyObject *
1779posix_fchdir(PyObject *self, PyObject *fdobj)
1780{
1781 return posix_fildes(fdobj, fchdir);
1782}
1783#endif /* HAVE_FCHDIR */
1784
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001785
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001786PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001787"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001788Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001789
Barry Warsaw53699e91996-12-10 23:23:01 +00001790static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001791posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001792{
Martin v. Löwis011e8422009-05-05 04:43:17 +00001793 PyObject *opath = NULL;
Mark Hammondef8b6542001-05-13 08:04:26 +00001794 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001795 int i;
1796 int res;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001797#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001798 DWORD attr;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001799 PyUnicodeObject *po;
1800 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1801 Py_BEGIN_ALLOW_THREADS
1802 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1803 if (attr != 0xFFFFFFFF) {
1804 if (i & _S_IWRITE)
1805 attr &= ~FILE_ATTRIBUTE_READONLY;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001806 else
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001807 attr |= FILE_ATTRIBUTE_READONLY;
1808 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
Mark Hammond817c9292003-12-03 01:22:38 +00001809 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001810 else
1811 res = 0;
1812 Py_END_ALLOW_THREADS
1813 if (!res)
1814 return win32_error_unicode("chmod",
1815 PyUnicode_AS_UNICODE(po));
1816 Py_INCREF(Py_None);
1817 return Py_None;
Mark Hammond817c9292003-12-03 01:22:38 +00001818 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001819 /* Drop the argument parsing error as narrow strings
1820 are also valid. */
1821 PyErr_Clear();
1822
Martin v. Löwis011e8422009-05-05 04:43:17 +00001823 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1824 &opath, &i))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001825 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001826 path = bytes2str(opath, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001827 Py_BEGIN_ALLOW_THREADS
1828 attr = GetFileAttributesA(path);
1829 if (attr != 0xFFFFFFFF) {
1830 if (i & _S_IWRITE)
1831 attr &= ~FILE_ATTRIBUTE_READONLY;
1832 else
1833 attr |= FILE_ATTRIBUTE_READONLY;
1834 res = SetFileAttributesA(path, attr);
1835 }
1836 else
1837 res = 0;
1838 Py_END_ALLOW_THREADS
1839 if (!res) {
1840 win32_error("chmod", path);
Martin v. Löwis011e8422009-05-05 04:43:17 +00001841 release_bytes(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001842 return NULL;
1843 }
Martin v. Löwis011e8422009-05-05 04:43:17 +00001844 release_bytes(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001845 Py_INCREF(Py_None);
1846 return Py_None;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001847#else /* MS_WINDOWS */
Martin v. Löwis011e8422009-05-05 04:43:17 +00001848 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1849 &opath, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001850 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001851 path = bytes2str(opath, 1);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001852 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001853 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001854 Py_END_ALLOW_THREADS
1855 if (res < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +00001856 return posix_error_with_allocated_filename(opath);
1857 release_bytes(opath);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001858 Py_INCREF(Py_None);
1859 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001860#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001861}
1862
Christian Heimes4e30a842007-11-30 22:12:06 +00001863#ifdef HAVE_FCHMOD
1864PyDoc_STRVAR(posix_fchmod__doc__,
1865"fchmod(fd, mode)\n\n\
1866Change the access permissions of the file given by file\n\
1867descriptor fd.");
1868
1869static PyObject *
1870posix_fchmod(PyObject *self, PyObject *args)
1871{
1872 int fd, mode, res;
1873 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1874 return NULL;
1875 Py_BEGIN_ALLOW_THREADS
1876 res = fchmod(fd, mode);
1877 Py_END_ALLOW_THREADS
1878 if (res < 0)
1879 return posix_error();
1880 Py_RETURN_NONE;
1881}
1882#endif /* HAVE_FCHMOD */
1883
1884#ifdef HAVE_LCHMOD
1885PyDoc_STRVAR(posix_lchmod__doc__,
1886"lchmod(path, mode)\n\n\
1887Change the access permissions of a file. If path is a symlink, this\n\
1888affects the link itself rather than the target.");
1889
1890static PyObject *
1891posix_lchmod(PyObject *self, PyObject *args)
1892{
Martin v. Löwis011e8422009-05-05 04:43:17 +00001893 PyObject *opath;
1894 char *path;
Christian Heimes4e30a842007-11-30 22:12:06 +00001895 int i;
1896 int res;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001897 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
1898 &opath, &i))
Christian Heimes4e30a842007-11-30 22:12:06 +00001899 return NULL;
Eric Smith86a05ec2009-05-05 13:07:30 +00001900 path = bytes2str(opath, 1);
Christian Heimes4e30a842007-11-30 22:12:06 +00001901 Py_BEGIN_ALLOW_THREADS
1902 res = lchmod(path, i);
1903 Py_END_ALLOW_THREADS
1904 if (res < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +00001905 return posix_error_with_allocated_filename(opath);
1906 release_bytes(opath);
Christian Heimes4e30a842007-11-30 22:12:06 +00001907 Py_RETURN_NONE;
1908}
1909#endif /* HAVE_LCHMOD */
1910
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001911
Thomas Wouterscf297e42007-02-23 15:07:44 +00001912#ifdef HAVE_CHFLAGS
1913PyDoc_STRVAR(posix_chflags__doc__,
1914"chflags(path, flags)\n\n\
1915Set file flags.");
1916
1917static PyObject *
1918posix_chflags(PyObject *self, PyObject *args)
1919{
Martin v. Löwis011e8422009-05-05 04:43:17 +00001920 PyObject *opath;
Thomas Wouterscf297e42007-02-23 15:07:44 +00001921 char *path;
1922 unsigned long flags;
1923 int res;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001924 if (!PyArg_ParseTuple(args, "O&k:chflags",
1925 PyUnicode_FSConverter, &opath, &flags))
Thomas Wouterscf297e42007-02-23 15:07:44 +00001926 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001927 path = bytes2str(opath, 1);
Thomas Wouterscf297e42007-02-23 15:07:44 +00001928 Py_BEGIN_ALLOW_THREADS
1929 res = chflags(path, flags);
1930 Py_END_ALLOW_THREADS
1931 if (res < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +00001932 return posix_error_with_allocated_filename(opath);
1933 release_bytes(opath);
Thomas Wouterscf297e42007-02-23 15:07:44 +00001934 Py_INCREF(Py_None);
1935 return Py_None;
1936}
1937#endif /* HAVE_CHFLAGS */
1938
1939#ifdef HAVE_LCHFLAGS
1940PyDoc_STRVAR(posix_lchflags__doc__,
1941"lchflags(path, flags)\n\n\
1942Set file flags.\n\
1943This function will not follow symbolic links.");
1944
1945static PyObject *
1946posix_lchflags(PyObject *self, PyObject *args)
1947{
Martin v. Löwis011e8422009-05-05 04:43:17 +00001948 PyObject *opath;
Thomas Wouterscf297e42007-02-23 15:07:44 +00001949 char *path;
1950 unsigned long flags;
1951 int res;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001952 if (!PyArg_ParseTuple(args, "O&k:lchflags",
Martin v. Löwis4adbc342009-05-05 17:17:55 +00001953 PyUnicode_FSConverter, &opath, &flags))
Thomas Wouterscf297e42007-02-23 15:07:44 +00001954 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001955 path = bytes2str(opath, 1);
Thomas Wouterscf297e42007-02-23 15:07:44 +00001956 Py_BEGIN_ALLOW_THREADS
1957 res = lchflags(path, flags);
1958 Py_END_ALLOW_THREADS
1959 if (res < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +00001960 return posix_error_with_allocated_filename(opath);
1961 release_bytes(opath);
Thomas Wouterscf297e42007-02-23 15:07:44 +00001962 Py_INCREF(Py_None);
1963 return Py_None;
1964}
1965#endif /* HAVE_LCHFLAGS */
1966
Martin v. Löwis244edc82001-10-04 22:44:26 +00001967#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001968PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001969"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001970Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001971
1972static PyObject *
1973posix_chroot(PyObject *self, PyObject *args)
1974{
Martin v. Löwis011e8422009-05-05 04:43:17 +00001975 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001976}
1977#endif
1978
Guido van Rossum21142a01999-01-08 21:05:37 +00001979#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001980PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001981"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001982force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001983
1984static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001985posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001986{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001987 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001988}
1989#endif /* HAVE_FSYNC */
1990
1991#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001992
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001993#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001994extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1995#endif
1996
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001997PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001998"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001999force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002000 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002001
2002static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002003posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002004{
Fred Drake4d1e64b2002-04-15 19:40:07 +00002005 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002006}
2007#endif /* HAVE_FDATASYNC */
2008
2009
Fredrik Lundh10723342000-07-10 16:38:09 +00002010#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002011PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002012"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002013Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002014
Barry Warsaw53699e91996-12-10 23:23:01 +00002015static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002016posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002017{
Martin v. Löwis011e8422009-05-05 04:43:17 +00002018 PyObject *opath;
2019 char *path;
Christian Heimesd5e2b6f2008-03-19 21:50:51 +00002020 long uid, gid;
Fredrik Lundh44328e62000-07-10 15:59:30 +00002021 int res;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002022 if (!PyArg_ParseTuple(args, "O&ll:chown",
2023 PyUnicode_FSConverter, &opath,
Mark Hammondef8b6542001-05-13 08:04:26 +00002024 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00002025 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002026 path = bytes2str(opath, 1);
Fredrik Lundh44328e62000-07-10 15:59:30 +00002027 Py_BEGIN_ALLOW_THREADS
2028 res = chown(path, (uid_t) uid, (gid_t) gid);
2029 Py_END_ALLOW_THREADS
2030 if (res < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +00002031 return posix_error_with_allocated_filename(opath);
2032 release_bytes(opath);
Fredrik Lundh44328e62000-07-10 15:59:30 +00002033 Py_INCREF(Py_None);
2034 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002035}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002036#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002037
Christian Heimes4e30a842007-11-30 22:12:06 +00002038#ifdef HAVE_FCHOWN
2039PyDoc_STRVAR(posix_fchown__doc__,
2040"fchown(fd, uid, gid)\n\n\
2041Change the owner and group id of the file given by file descriptor\n\
2042fd to the numeric uid and gid.");
2043
2044static PyObject *
2045posix_fchown(PyObject *self, PyObject *args)
2046{
2047 int fd, uid, gid;
2048 int res;
2049 if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid))
2050 return NULL;
2051 Py_BEGIN_ALLOW_THREADS
2052 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2053 Py_END_ALLOW_THREADS
2054 if (res < 0)
2055 return posix_error();
2056 Py_RETURN_NONE;
2057}
2058#endif /* HAVE_FCHOWN */
2059
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002060#ifdef HAVE_LCHOWN
2061PyDoc_STRVAR(posix_lchown__doc__,
2062"lchown(path, uid, gid)\n\n\
2063Change the owner and group id of path to the numeric uid and gid.\n\
2064This function will not follow symbolic links.");
2065
2066static PyObject *
2067posix_lchown(PyObject *self, PyObject *args)
2068{
Martin v. Löwis011e8422009-05-05 04:43:17 +00002069 PyObject *opath;
2070 char *path;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002071 int uid, gid;
2072 int res;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002073 if (!PyArg_ParseTuple(args, "O&ii:lchown",
2074 PyUnicode_FSConverter, &opath,
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002075 &uid, &gid))
2076 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002077 path = bytes2str(opath, 1);
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002078 Py_BEGIN_ALLOW_THREADS
2079 res = lchown(path, (uid_t) uid, (gid_t) gid);
2080 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00002081 if (res < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +00002082 return posix_error_with_allocated_filename(opath);
2083 release_bytes(opath);
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002084 Py_INCREF(Py_None);
2085 return Py_None;
2086}
2087#endif /* HAVE_LCHOWN */
2088
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002089
Guido van Rossum36bc6801995-06-14 22:54:23 +00002090#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002091static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002092posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002093{
2094 char buf[1026];
2095 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002096
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002097#ifdef MS_WINDOWS
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002098 if (!use_bytes) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002099 wchar_t wbuf[1026];
Thomas Wouters477c8d52006-05-27 19:21:47 +00002100 wchar_t *wbuf2 = wbuf;
2101 PyObject *resobj;
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002102 DWORD len;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002103 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002104 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2105 /* If the buffer is large enough, len does not include the
2106 terminating \0. If the buffer is too small, len includes
2107 the space needed for the terminator. */
2108 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2109 wbuf2 = malloc(len * sizeof(wchar_t));
2110 if (wbuf2)
2111 len = GetCurrentDirectoryW(len, wbuf2);
2112 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002113 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002114 if (!wbuf2) {
2115 PyErr_NoMemory();
2116 return NULL;
2117 }
2118 if (!len) {
2119 if (wbuf2 != wbuf) free(wbuf2);
2120 return win32_error("getcwdu", NULL);
2121 }
2122 resobj = PyUnicode_FromWideChar(wbuf2, len);
2123 if (wbuf2 != wbuf) free(wbuf2);
2124 return resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002125 }
2126#endif
2127
2128 Py_BEGIN_ALLOW_THREADS
2129#if defined(PYOS_OS2) && defined(PYCC_GCC)
2130 res = _getcwd2(buf, sizeof buf);
2131#else
2132 res = getcwd(buf, sizeof buf);
2133#endif
2134 Py_END_ALLOW_THREADS
2135 if (res == NULL)
2136 return posix_error();
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002137 if (use_bytes)
2138 return PyBytes_FromStringAndSize(buf, strlen(buf));
Martin v. Löwis43c57782009-05-10 08:15:24 +00002139 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"surrogateescape");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002140}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002141
2142PyDoc_STRVAR(posix_getcwd__doc__,
2143"getcwd() -> path\n\n\
2144Return a unicode string representing the current working directory.");
2145
2146static PyObject *
2147posix_getcwd_unicode(PyObject *self)
2148{
2149 return posix_getcwd(0);
2150}
2151
2152PyDoc_STRVAR(posix_getcwdb__doc__,
2153"getcwdb() -> path\n\n\
2154Return a bytes string representing the current working directory.");
2155
2156static PyObject *
2157posix_getcwd_bytes(PyObject *self)
2158{
2159 return posix_getcwd(1);
2160}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002161#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002162
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002163
Guido van Rossumb6775db1994-08-01 11:34:53 +00002164#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002165PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002166"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002167Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002168
Barry Warsaw53699e91996-12-10 23:23:01 +00002169static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002170posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002171{
Martin v. Löwis011e8422009-05-05 04:43:17 +00002172 return posix_2str(args, "O&O&:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002173}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002174#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002175
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002176
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002177PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002178"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002179Return a list containing the names of the entries in the directory.\n\
2180\n\
2181 path: path of directory to list\n\
2182\n\
2183The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002184entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002185
Barry Warsaw53699e91996-12-10 23:23:01 +00002186static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002187posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002188{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002189 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002190 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002191#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002192
Barry Warsaw53699e91996-12-10 23:23:01 +00002193 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002194 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002195 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002196 WIN32_FIND_DATA FileData;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002197 PyObject *opath;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002198 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00002199 char *bufptr = namebuf;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002200 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002201
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002202 PyObject *po;
2203 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2204 WIN32_FIND_DATAW wFileData;
2205 Py_UNICODE *wnamebuf;
2206 /* Overallocate for \\*.*\0 */
2207 len = PyUnicode_GET_SIZE(po);
2208 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2209 if (!wnamebuf) {
2210 PyErr_NoMemory();
2211 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002212 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002213 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2214 if (len > 0) {
2215 Py_UNICODE wch = wnamebuf[len-1];
2216 if (wch != L'/' && wch != L'\\' && wch != L':')
2217 wnamebuf[len++] = L'\\';
2218 wcscpy(wnamebuf + len, L"*.*");
2219 }
2220 if ((d = PyList_New(0)) == NULL) {
2221 free(wnamebuf);
2222 return NULL;
2223 }
2224 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2225 if (hFindFile == INVALID_HANDLE_VALUE) {
2226 int error = GetLastError();
2227 if (error == ERROR_FILE_NOT_FOUND) {
2228 free(wnamebuf);
2229 return d;
2230 }
2231 Py_DECREF(d);
2232 win32_error_unicode("FindFirstFileW", wnamebuf);
2233 free(wnamebuf);
2234 return NULL;
2235 }
2236 do {
2237 /* Skip over . and .. */
2238 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2239 wcscmp(wFileData.cFileName, L"..") != 0) {
2240 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2241 if (v == NULL) {
2242 Py_DECREF(d);
2243 d = NULL;
2244 break;
2245 }
2246 if (PyList_Append(d, v) != 0) {
2247 Py_DECREF(v);
2248 Py_DECREF(d);
2249 d = NULL;
2250 break;
2251 }
2252 Py_DECREF(v);
2253 }
2254 Py_BEGIN_ALLOW_THREADS
2255 result = FindNextFileW(hFindFile, &wFileData);
2256 Py_END_ALLOW_THREADS
2257 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2258 it got to the end of the directory. */
2259 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2260 Py_DECREF(d);
2261 win32_error_unicode("FindNextFileW", wnamebuf);
2262 FindClose(hFindFile);
2263 free(wnamebuf);
2264 return NULL;
2265 }
2266 } while (result == TRUE);
2267
2268 if (FindClose(hFindFile) == FALSE) {
2269 Py_DECREF(d);
2270 win32_error_unicode("FindClose", wnamebuf);
2271 free(wnamebuf);
2272 return NULL;
2273 }
2274 free(wnamebuf);
2275 return d;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002276 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002277 /* Drop the argument parsing error as narrow strings
2278 are also valid. */
2279 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002280
Martin v. Löwis011e8422009-05-05 04:43:17 +00002281 if (!PyArg_ParseTuple(args, "O&:listdir",
2282 PyUnicode_FSConverter, &opath))
Guido van Rossumb6775db1994-08-01 11:34:53 +00002283 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002284 if (PyObject_Size(opath)+1 > MAX_PATH) {
2285 PyErr_SetString(PyExc_ValueError, "path too long");
2286 Py_DECREF(opath);
2287 return NULL;
2288 }
2289 strcpy(namebuf, bytes2str(opath, 0));
2290 len = PyObject_Size(opath);
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002291 if (len > 0) {
2292 char ch = namebuf[len-1];
2293 if (ch != SEP && ch != ALTSEP && ch != ':')
2294 namebuf[len++] = '/';
Hirokazu Yamamotobbb9be72009-05-04 05:56:46 +00002295 strcpy(namebuf + len, "*.*");
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002296 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002297
Barry Warsaw53699e91996-12-10 23:23:01 +00002298 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002299 return NULL;
2300
2301 hFindFile = FindFirstFile(namebuf, &FileData);
2302 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002303 int error = GetLastError();
2304 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002305 return d;
2306 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002307 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002308 }
2309 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002310 /* Skip over . and .. */
2311 if (strcmp(FileData.cFileName, ".") != 0 &&
2312 strcmp(FileData.cFileName, "..") != 0) {
Christian Heimes72b710a2008-05-26 13:28:38 +00002313 v = PyBytes_FromString(FileData.cFileName);
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002314 if (v == NULL) {
2315 Py_DECREF(d);
2316 d = NULL;
2317 break;
2318 }
2319 if (PyList_Append(d, v) != 0) {
2320 Py_DECREF(v);
2321 Py_DECREF(d);
2322 d = NULL;
2323 break;
2324 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002325 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002326 }
Georg Brandl622927b2006-03-07 12:48:03 +00002327 Py_BEGIN_ALLOW_THREADS
2328 result = FindNextFile(hFindFile, &FileData);
2329 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002330 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2331 it got to the end of the directory. */
2332 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2333 Py_DECREF(d);
2334 win32_error("FindNextFile", namebuf);
2335 FindClose(hFindFile);
2336 return NULL;
2337 }
Georg Brandl622927b2006-03-07 12:48:03 +00002338 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002339
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002340 if (FindClose(hFindFile) == FALSE) {
2341 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002342 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002343 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002344
2345 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002346
Tim Peters0bb44a42000-09-15 07:44:49 +00002347#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002348
2349#ifndef MAX_PATH
2350#define MAX_PATH CCHMAXPATH
2351#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002352 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002353 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002354 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002355 PyObject *d, *v;
2356 char namebuf[MAX_PATH+5];
2357 HDIR hdir = 1;
2358 ULONG srchcnt = 1;
2359 FILEFINDBUF3 ep;
2360 APIRET rc;
2361
Martin v. Löwis011e8422009-05-05 04:43:17 +00002362 if (!PyArg_ParseTuple(args, "O&:listdir",
2363 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002364 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002365 name = bytes2str(oname);
2366 len = PyObject_Size(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002367 if (len >= MAX_PATH) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00002368 release_bytes(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002369 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002370 return NULL;
2371 }
2372 strcpy(namebuf, name);
2373 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002374 if (*pt == ALTSEP)
2375 *pt = SEP;
2376 if (namebuf[len-1] != SEP)
2377 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002378 strcpy(namebuf + len, "*.*");
2379
Neal Norwitz6c913782007-10-14 03:23:09 +00002380 if ((d = PyList_New(0)) == NULL) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00002381 release_bytes(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002382 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002383 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002384
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002385 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2386 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002387 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002388 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2389 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2390 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002391
2392 if (rc != NO_ERROR) {
2393 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002394 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002395 }
2396
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002397 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002398 do {
2399 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002400 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002401 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002402
2403 strcpy(namebuf, ep.achName);
2404
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002405 /* Leave Case of Name Alone -- In Native Form */
2406 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002407
Christian Heimes72b710a2008-05-26 13:28:38 +00002408 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002409 if (v == NULL) {
2410 Py_DECREF(d);
2411 d = NULL;
2412 break;
2413 }
2414 if (PyList_Append(d, v) != 0) {
2415 Py_DECREF(v);
2416 Py_DECREF(d);
2417 d = NULL;
2418 break;
2419 }
2420 Py_DECREF(v);
2421 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2422 }
2423
Martin v. Löwis011e8422009-05-05 04:43:17 +00002424 release_bytes(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002425 return d;
2426#else
Martin v. Löwis011e8422009-05-05 04:43:17 +00002427 PyObject *oname;
2428 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00002429 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002430 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002431 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00002432 int arg_is_unicode = 1;
2433
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002434 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002435 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2436 arg_is_unicode = 0;
2437 PyErr_Clear();
2438 }
Martin v. Löwis011e8422009-05-05 04:43:17 +00002439 if (!PyArg_ParseTuple(args, "O&:listdir", PyUnicode_FSConverter, &oname))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002440 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002441 name = bytes2str(oname, 1);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002442 if ((dirp = opendir(name)) == NULL) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00002443 return posix_error_with_allocated_filename(oname);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002444 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002445 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002446 closedir(dirp);
Martin v. Löwis011e8422009-05-05 04:43:17 +00002447 release_bytes(oname);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002448 return NULL;
2449 }
Georg Brandl622927b2006-03-07 12:48:03 +00002450 for (;;) {
Georg Brandl3dbca812008-07-23 16:10:53 +00002451 errno = 0;
Georg Brandl622927b2006-03-07 12:48:03 +00002452 Py_BEGIN_ALLOW_THREADS
2453 ep = readdir(dirp);
2454 Py_END_ALLOW_THREADS
Georg Brandl3dbca812008-07-23 16:10:53 +00002455 if (ep == NULL) {
2456 if (errno == 0) {
2457 break;
2458 } else {
2459 closedir(dirp);
2460 Py_DECREF(d);
Martin v. Löwis011e8422009-05-05 04:43:17 +00002461 return posix_error_with_allocated_filename(oname);
Georg Brandl3dbca812008-07-23 16:10:53 +00002462 }
2463 }
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002464 if (ep->d_name[0] == '.' &&
2465 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002466 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002467 continue;
Christian Heimes72b710a2008-05-26 13:28:38 +00002468 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002469 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002470 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002471 d = NULL;
2472 break;
2473 }
Just van Rossum96b1c902003-03-03 17:32:15 +00002474 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002475 PyObject *w;
2476
2477 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002478 Py_FileSystemDefaultEncoding,
Martin v. Löwis43c57782009-05-10 08:15:24 +00002479 "surrogateescape");
Martin v. Löwis011e8422009-05-05 04:43:17 +00002480 Py_DECREF(v);
2481 if (w != NULL)
Just van Rossum6a421832003-03-04 19:30:44 +00002482 v = w;
Just van Rossum6a421832003-03-04 19:30:44 +00002483 else {
Martin v. Löwis011e8422009-05-05 04:43:17 +00002484 /* Encoding failed to decode ASCII bytes.
2485 Raise exception. */
2486 Py_DECREF(d);
2487 d = NULL;
2488 break;
Just van Rossum46c97842003-02-25 21:42:15 +00002489 }
Just van Rossum46c97842003-02-25 21:42:15 +00002490 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002491 if (PyList_Append(d, v) != 0) {
2492 Py_DECREF(v);
2493 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002494 d = NULL;
2495 break;
2496 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002497 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002498 }
2499 closedir(dirp);
Martin v. Löwis011e8422009-05-05 04:43:17 +00002500 release_bytes(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002501
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002502 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002503
Tim Peters0bb44a42000-09-15 07:44:49 +00002504#endif /* which OS */
2505} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002506
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002507#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002508/* A helper function for abspath on win32 */
2509static PyObject *
2510posix__getfullpathname(PyObject *self, PyObject *args)
2511{
Martin v. Löwis011e8422009-05-05 04:43:17 +00002512 PyObject *opath;
2513 char *path;
Mark Hammondef8b6542001-05-13 08:04:26 +00002514 char outbuf[MAX_PATH*2];
2515 char *temp;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002516#ifdef MS_WINDOWS
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002517 PyUnicodeObject *po;
2518 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2519 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2520 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2521 Py_UNICODE *wtemp;
2522 DWORD result;
2523 PyObject *v;
2524 result = GetFullPathNameW(wpath,
2525 sizeof(woutbuf)/sizeof(woutbuf[0]),
2526 woutbuf, &wtemp);
2527 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2528 woutbufp = malloc(result * sizeof(Py_UNICODE));
2529 if (!woutbufp)
2530 return PyErr_NoMemory();
2531 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002532 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002533 if (result)
2534 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2535 else
2536 v = win32_error_unicode("GetFullPathNameW", wpath);
2537 if (woutbufp != woutbuf)
2538 free(woutbufp);
2539 return v;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002540 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002541 /* Drop the argument parsing error as narrow strings
2542 are also valid. */
2543 PyErr_Clear();
2544
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002545#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002546 if (!PyArg_ParseTuple (args, "O&:_getfullpathname",
2547 PyUnicode_FSConverter, &opath))
Mark Hammondef8b6542001-05-13 08:04:26 +00002548 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002549 path = bytes2str(opath, 1);
2550 if (!GetFullPathName(path, sizeof(outbuf)/sizeof(outbuf[0]),
2551 outbuf, &temp)) {
2552 win32_error("GetFullPathName", path);
2553 release_bytes(opath);
2554 return NULL;
2555 }
2556 release_bytes(opath);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002557 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2558 return PyUnicode_Decode(outbuf, strlen(outbuf),
2559 Py_FileSystemDefaultEncoding, NULL);
2560 }
Christian Heimes72b710a2008-05-26 13:28:38 +00002561 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002562} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002563#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002564
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002565PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002566"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002567Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002568
Barry Warsaw53699e91996-12-10 23:23:01 +00002569static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002570posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002571{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002572 int res;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002573 PyObject *opath;
2574 char *path;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002575 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002576
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002577#ifdef MS_WINDOWS
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002578 PyUnicodeObject *po;
2579 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2580 Py_BEGIN_ALLOW_THREADS
2581 /* PyUnicode_AS_UNICODE OK without thread lock as
2582 it is a simple dereference. */
2583 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2584 Py_END_ALLOW_THREADS
2585 if (!res)
2586 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2587 Py_INCREF(Py_None);
2588 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002589 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002590 /* Drop the argument parsing error as narrow strings
2591 are also valid. */
2592 PyErr_Clear();
Martin v. Löwis011e8422009-05-05 04:43:17 +00002593 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2594 PyUnicode_FSConverter, &opath, &mode))
Thomas Wouters477c8d52006-05-27 19:21:47 +00002595 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002596 path = bytes2str(opath, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002597 Py_BEGIN_ALLOW_THREADS
2598 /* PyUnicode_AS_UNICODE OK without thread lock as
2599 it is a simple dereference. */
2600 res = CreateDirectoryA(path, NULL);
2601 Py_END_ALLOW_THREADS
2602 if (!res) {
2603 win32_error("mkdir", path);
Martin v. Löwis011e8422009-05-05 04:43:17 +00002604 release_bytes(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002605 return NULL;
2606 }
Martin v. Löwis011e8422009-05-05 04:43:17 +00002607 release_bytes(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002608 Py_INCREF(Py_None);
2609 return Py_None;
2610#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002611
Martin v. Löwis011e8422009-05-05 04:43:17 +00002612 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2613 PyUnicode_FSConverter, &opath, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002614 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002615 path = bytes2str(opath, 1);
Barry Warsaw53699e91996-12-10 23:23:01 +00002616 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002617#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002618 res = mkdir(path);
2619#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002620 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002621#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002622 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002623 if (res < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +00002624 return posix_error_with_allocated_filename(opath);
2625 release_bytes(opath);
Barry Warsaw53699e91996-12-10 23:23:01 +00002626 Py_INCREF(Py_None);
2627 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002628#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002629}
2630
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002631
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002632/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2633#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002634#include <sys/resource.h>
2635#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002636
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002637
2638#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002639PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002640"nice(inc) -> new_priority\n\n\
2641Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002642
Barry Warsaw53699e91996-12-10 23:23:01 +00002643static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002644posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002645{
2646 int increment, value;
2647
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002648 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002649 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002650
2651 /* There are two flavours of 'nice': one that returns the new
2652 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002653 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2654 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002655
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002656 If we are of the nice family that returns the new priority, we
2657 need to clear errno before the call, and check if errno is filled
2658 before calling posix_error() on a returnvalue of -1, because the
2659 -1 may be the actual new priority! */
2660
2661 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002662 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002663#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002664 if (value == 0)
2665 value = getpriority(PRIO_PROCESS, 0);
2666#endif
2667 if (value == -1 && errno != 0)
2668 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002669 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00002670 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002671}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002672#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002673
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002674PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002675"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002676Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002677
Barry Warsaw53699e91996-12-10 23:23:01 +00002678static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002679posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002680{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002681#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002682 PyObject *o1, *o2;
2683 char *p1, *p2;
2684 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002685 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +00002686 goto error;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002687 if (!convert_to_unicode(&o1))
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +00002688 goto error;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002689 if (!convert_to_unicode(&o2)) {
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +00002690 Py_DECREF(o1);
2691 goto error;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002692 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002693 Py_BEGIN_ALLOW_THREADS
2694 result = MoveFileW(PyUnicode_AsUnicode(o1),
2695 PyUnicode_AsUnicode(o2));
2696 Py_END_ALLOW_THREADS
2697 Py_DECREF(o1);
2698 Py_DECREF(o2);
2699 if (!result)
2700 return win32_error("rename", NULL);
2701 Py_INCREF(Py_None);
2702 return Py_None;
2703error:
2704 PyErr_Clear();
Thomas Wouters477c8d52006-05-27 19:21:47 +00002705 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2706 return NULL;
2707 Py_BEGIN_ALLOW_THREADS
2708 result = MoveFileA(p1, p2);
2709 Py_END_ALLOW_THREADS
2710 if (!result)
2711 return win32_error("rename", NULL);
2712 Py_INCREF(Py_None);
2713 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002714#else
Martin v. Löwis011e8422009-05-05 04:43:17 +00002715 return posix_2str(args, "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002716#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002717}
2718
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002719
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002720PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002721"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002722Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002723
Barry Warsaw53699e91996-12-10 23:23:01 +00002724static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002725posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002726{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002727#ifdef MS_WINDOWS
Amaury Forgeot d'Arcc72ef8b2008-10-03 18:38:26 +00002728 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002729#else
Martin v. Löwis011e8422009-05-05 04:43:17 +00002730 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002731#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002732}
2733
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002734
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002735PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002736"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002737Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002738
Barry Warsaw53699e91996-12-10 23:23:01 +00002739static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002740posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002741{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002742#ifdef MS_WINDOWS
Martin v. Löwis011e8422009-05-05 04:43:17 +00002743 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002744#else
Martin v. Löwis011e8422009-05-05 04:43:17 +00002745 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002746#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002747}
2748
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002749
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002750#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002751PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002752"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002753Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002754
Barry Warsaw53699e91996-12-10 23:23:01 +00002755static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002756posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002757{
Guido van Rossumff4949e1992-08-05 19:58:53 +00002758 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002759#ifdef MS_WINDOWS
2760 wchar_t *command;
2761 if (!PyArg_ParseTuple(args, "u:system", &command))
2762 return NULL;
2763#else
2764 char *command;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002765 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002766 return NULL;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002767#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002768 Py_BEGIN_ALLOW_THREADS
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002769#ifdef MS_WINDOWS
2770 sts = _wsystem(command);
2771#else
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002772 sts = system(command);
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002773#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002774 Py_END_ALLOW_THREADS
Christian Heimes217cfd12007-12-02 14:31:20 +00002775 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002776}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002777#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002778
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002779
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002780PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002781"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002782Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002783
Barry Warsaw53699e91996-12-10 23:23:01 +00002784static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002785posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002786{
2787 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002788 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002789 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002790 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002791 if (i < 0)
2792 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00002793 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002794}
2795
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002796
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002797PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002798"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002799Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002800
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002801PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002802"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002803Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002804
Barry Warsaw53699e91996-12-10 23:23:01 +00002805static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002806posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002807{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002808#ifdef MS_WINDOWS
Amaury Forgeot d'Arcc72ef8b2008-10-03 18:38:26 +00002809 return win32_1str(args, "remove", "y:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002810#else
Martin v. Löwis011e8422009-05-05 04:43:17 +00002811 return posix_1str(args, "O&:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002812#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002813}
2814
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002815
Guido van Rossumb6775db1994-08-01 11:34:53 +00002816#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002817PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002818"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002819Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002820
Barry Warsaw53699e91996-12-10 23:23:01 +00002821static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002822posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002823{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002824 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002825 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002826
Barry Warsaw53699e91996-12-10 23:23:01 +00002827 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002828 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002829 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002830 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002831 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002832 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002833 u.sysname,
2834 u.nodename,
2835 u.release,
2836 u.version,
2837 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002838}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002839#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002840
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002841static int
2842extract_time(PyObject *t, long* sec, long* usec)
2843{
2844 long intval;
2845 if (PyFloat_Check(t)) {
2846 double tval = PyFloat_AsDouble(t);
Christian Heimes90aa7642007-12-19 02:45:37 +00002847 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002848 if (!intobj)
2849 return -1;
Christian Heimes217cfd12007-12-02 14:31:20 +00002850 intval = PyLong_AsLong(intobj);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002851 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002852 if (intval == -1 && PyErr_Occurred())
2853 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002854 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002855 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002856 if (*usec < 0)
2857 /* If rounding gave us a negative number,
2858 truncate. */
2859 *usec = 0;
2860 return 0;
2861 }
Christian Heimes217cfd12007-12-02 14:31:20 +00002862 intval = PyLong_AsLong(t);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002863 if (intval == -1 && PyErr_Occurred())
2864 return -1;
2865 *sec = intval;
2866 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002867 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002868}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002869
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002870PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002871"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002872utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002873Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002874second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002875
Barry Warsaw53699e91996-12-10 23:23:01 +00002876static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002877posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002878{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002879#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002880 PyObject *arg;
2881 PyUnicodeObject *obwpath;
2882 wchar_t *wpath = NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002883 PyObject *oapath;
2884 char *apath;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002885 HANDLE hFile;
2886 long atimesec, mtimesec, ausec, musec;
2887 FILETIME atime, mtime;
2888 PyObject *result = NULL;
2889
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002890 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2891 wpath = PyUnicode_AS_UNICODE(obwpath);
2892 Py_BEGIN_ALLOW_THREADS
2893 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
2894 NULL, OPEN_EXISTING,
2895 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2896 Py_END_ALLOW_THREADS
2897 if (hFile == INVALID_HANDLE_VALUE)
2898 return win32_error_unicode("utime", wpath);
2899 } else
2900 /* Drop the argument parsing error as narrow strings
2901 are also valid. */
2902 PyErr_Clear();
2903
Thomas Wouters477c8d52006-05-27 19:21:47 +00002904 if (!wpath) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00002905 if (!PyArg_ParseTuple(args, "O&O:utime",
2906 PyUnicode_FSConverter, &oapath, &arg))
Thomas Wouters477c8d52006-05-27 19:21:47 +00002907 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002908 apath = bytes2str(oapath, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002909 Py_BEGIN_ALLOW_THREADS
2910 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
Thomas Wouters89f507f2006-12-13 04:49:30 +00002911 NULL, OPEN_EXISTING,
2912 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002913 Py_END_ALLOW_THREADS
2914 if (hFile == INVALID_HANDLE_VALUE) {
2915 win32_error("utime", apath);
Martin v. Löwis011e8422009-05-05 04:43:17 +00002916 release_bytes(oapath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002917 return NULL;
2918 }
Martin v. Löwis011e8422009-05-05 04:43:17 +00002919 release_bytes(oapath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002920 }
2921
2922 if (arg == Py_None) {
2923 SYSTEMTIME now;
2924 GetSystemTime(&now);
2925 if (!SystemTimeToFileTime(&now, &mtime) ||
2926 !SystemTimeToFileTime(&now, &atime)) {
2927 win32_error("utime", NULL);
2928 goto done;
2929 }
2930 }
2931 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2932 PyErr_SetString(PyExc_TypeError,
2933 "utime() arg 2 must be a tuple (atime, mtime)");
2934 goto done;
2935 }
2936 else {
2937 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2938 &atimesec, &ausec) == -1)
2939 goto done;
Thomas Wouters89f507f2006-12-13 04:49:30 +00002940 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002941 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2942 &mtimesec, &musec) == -1)
2943 goto done;
Thomas Wouters89f507f2006-12-13 04:49:30 +00002944 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002945 }
2946 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2947 /* Avoid putting the file name into the error here,
2948 as that may confuse the user into believing that
2949 something is wrong with the file, when it also
2950 could be the time stamp that gives a problem. */
2951 win32_error("utime", NULL);
2952 }
2953 Py_INCREF(Py_None);
2954 result = Py_None;
2955done:
2956 CloseHandle(hFile);
2957 return result;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002958#else /* MS_WINDOWS */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002959
Martin v. Löwis011e8422009-05-05 04:43:17 +00002960 PyObject *opath;
2961 char *path;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002962 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002963 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002964 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002965
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002966#if defined(HAVE_UTIMES)
2967 struct timeval buf[2];
2968#define ATIME buf[0].tv_sec
2969#define MTIME buf[1].tv_sec
2970#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002971/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002972 struct utimbuf buf;
2973#define ATIME buf.actime
2974#define MTIME buf.modtime
2975#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002976#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002977 time_t buf[2];
2978#define ATIME buf[0]
2979#define MTIME buf[1]
2980#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002981#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002982
Mark Hammond817c9292003-12-03 01:22:38 +00002983
Martin v. Löwis011e8422009-05-05 04:43:17 +00002984 if (!PyArg_ParseTuple(args, "O&O:utime",
2985 PyUnicode_FSConverter, &opath, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002986 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002987 path = bytes2str(opath, 1);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002988 if (arg == Py_None) {
2989 /* optional time values not given */
2990 Py_BEGIN_ALLOW_THREADS
2991 res = utime(path, NULL);
2992 Py_END_ALLOW_THREADS
2993 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002994 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002995 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002996 "utime() arg 2 must be a tuple (atime, mtime)");
Martin v. Löwis011e8422009-05-05 04:43:17 +00002997 release_bytes(opath);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002998 return NULL;
2999 }
3000 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003001 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00003002 &atime, &ausec) == -1) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003003 release_bytes(opath);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003004 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00003005 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003006 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00003007 &mtime, &musec) == -1) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003008 release_bytes(opath);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003009 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00003010 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00003011 ATIME = atime;
3012 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003013#ifdef HAVE_UTIMES
3014 buf[0].tv_usec = ausec;
3015 buf[1].tv_usec = musec;
3016 Py_BEGIN_ALLOW_THREADS
3017 res = utimes(path, buf);
3018 Py_END_ALLOW_THREADS
3019#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00003020 Py_BEGIN_ALLOW_THREADS
3021 res = utime(path, UTIME_ARG);
3022 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00003023#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00003024 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00003025 if (res < 0) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003026 return posix_error_with_allocated_filename(opath);
Mark Hammond2d5914b2004-05-04 08:10:37 +00003027 }
Martin v. Löwis011e8422009-05-05 04:43:17 +00003028 release_bytes(opath);
Barry Warsaw53699e91996-12-10 23:23:01 +00003029 Py_INCREF(Py_None);
3030 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003031#undef UTIME_ARG
3032#undef ATIME
3033#undef MTIME
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003034#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003035}
3036
Guido van Rossum85e3b011991-06-03 12:42:10 +00003037
Guido van Rossum3b066191991-06-04 19:40:25 +00003038/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003039
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003040PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003041"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003042Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003043
Barry Warsaw53699e91996-12-10 23:23:01 +00003044static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003045posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003046{
3047 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003048 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003049 return NULL;
3050 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00003051 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003052}
3053
Martin v. Löwis114619e2002-10-07 06:44:21 +00003054#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3055static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003056free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003057{
Martin v. Löwis725507b2006-03-07 12:08:51 +00003058 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00003059 for (i = 0; i < count; i++)
3060 PyMem_Free(array[i]);
3061 PyMem_DEL(array);
3062}
Martin v. Löwis011e8422009-05-05 04:43:17 +00003063
Antoine Pitrou69f71142009-05-24 21:25:49 +00003064static
Martin v. Löwis011e8422009-05-05 04:43:17 +00003065int fsconvert_strdup(PyObject *o, char**out)
3066{
3067 PyObject *bytes;
3068 Py_ssize_t size;
3069 if (!PyUnicode_FSConverter(o, &bytes))
3070 return 0;
3071 size = PyObject_Size(bytes);
3072 *out = PyMem_Malloc(size+1);
3073 if (!*out)
3074 return 0;
3075 /* Don't lock bytes, as we hold the GIL */
3076 memcpy(*out, bytes2str(bytes, 0), size+1);
3077 Py_DECREF(bytes);
3078 return 1;
3079}
Martin v. Löwis114619e2002-10-07 06:44:21 +00003080#endif
3081
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003082
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003083#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003084PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003085"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003086Execute an executable path with arguments, replacing current process.\n\
3087\n\
3088 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003089 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003090
Barry Warsaw53699e91996-12-10 23:23:01 +00003091static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003092posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003093{
Martin v. Löwis011e8422009-05-05 04:43:17 +00003094 PyObject *opath;
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003095 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00003096 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003097 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00003098 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003099 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003100
Guido van Rossum89b33251993-10-22 14:26:06 +00003101 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00003102 argv is a list or tuple of strings. */
3103
Martin v. Löwis011e8422009-05-05 04:43:17 +00003104 if (!PyArg_ParseTuple(args, "O&O:execv",
3105 PyUnicode_FSConverter,
3106 &opath, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003107 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003108 path = bytes2str(opath, 1);
Barry Warsaw53699e91996-12-10 23:23:01 +00003109 if (PyList_Check(argv)) {
3110 argc = PyList_Size(argv);
3111 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003112 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003113 else if (PyTuple_Check(argv)) {
3114 argc = PyTuple_Size(argv);
3115 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003116 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003117 else {
Fred Drake661ea262000-10-24 19:57:45 +00003118 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis011e8422009-05-05 04:43:17 +00003119 release_bytes(opath);
Guido van Rossum50422b42000-04-26 20:34:28 +00003120 return NULL;
3121 }
Thomas Heller6790d602007-08-30 17:15:14 +00003122 if (argc < 1) {
3123 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Martin v. Löwis011e8422009-05-05 04:43:17 +00003124 release_bytes(opath);
Thomas Heller6790d602007-08-30 17:15:14 +00003125 return NULL;
3126 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003127
Barry Warsaw53699e91996-12-10 23:23:01 +00003128 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003129 if (argvlist == NULL) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003130 release_bytes(opath);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003131 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003132 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00003133 for (i = 0; i < argc; i++) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003134 if (!fsconvert_strdup((*getitem)(argv, i),
3135 &argvlist[i])) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003136 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00003137 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00003138 "execv() arg 2 must contain only strings");
Martin v. Löwis011e8422009-05-05 04:43:17 +00003139 release_bytes(opath);
Guido van Rossum50422b42000-04-26 20:34:28 +00003140 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003141
Guido van Rossum85e3b011991-06-03 12:42:10 +00003142 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00003143 }
3144 argvlist[argc] = NULL;
3145
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003146 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003147
Guido van Rossum85e3b011991-06-03 12:42:10 +00003148 /* If we get here it's definitely an error */
3149
Martin v. Löwis114619e2002-10-07 06:44:21 +00003150 free_string_array(argvlist, argc);
Martin v. Löwis011e8422009-05-05 04:43:17 +00003151 release_bytes(opath);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003152 return posix_error();
3153}
3154
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003155
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003156PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003157"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003158Execute a path with arguments and environment, replacing current process.\n\
3159\n\
3160 path: path of executable file\n\
3161 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003162 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003163
Barry Warsaw53699e91996-12-10 23:23:01 +00003164static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003165posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003166{
Martin v. Löwis011e8422009-05-05 04:43:17 +00003167 PyObject *opath;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003168 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00003169 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003170 char **argvlist;
3171 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003172 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00003173 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003174 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00003175 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003176
3177 /* execve has three arguments: (path, argv, env), where
3178 argv is a list or tuple of strings and env is a dictionary
3179 like posix.environ. */
3180
Martin v. Löwis011e8422009-05-05 04:43:17 +00003181 if (!PyArg_ParseTuple(args, "O&OO:execve",
3182 PyUnicode_FSConverter,
3183 &opath, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003184 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003185 path = bytes2str(opath, 1);
Barry Warsaw53699e91996-12-10 23:23:01 +00003186 if (PyList_Check(argv)) {
3187 argc = PyList_Size(argv);
3188 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003189 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003190 else if (PyTuple_Check(argv)) {
3191 argc = PyTuple_Size(argv);
3192 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003193 }
3194 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003195 PyErr_SetString(PyExc_TypeError,
3196 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003197 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003198 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003199 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003200 PyErr_SetString(PyExc_TypeError,
3201 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003202 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003203 }
3204
Barry Warsaw53699e91996-12-10 23:23:01 +00003205 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003206 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003207 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003208 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003209 }
3210 for (i = 0; i < argc; i++) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003211 if (!fsconvert_strdup((*getitem)(argv, i),
3212 &argvlist[i]))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003213 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003214 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003215 goto fail_1;
3216 }
3217 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003218 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003219 argvlist[argc] = NULL;
3220
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003221 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003222 if (i < 0)
3223 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00003224 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003225 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003226 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003227 goto fail_1;
3228 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003229 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003230 keys = PyMapping_Keys(env);
3231 vals = PyMapping_Values(env);
3232 if (!keys || !vals)
3233 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003234 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3235 PyErr_SetString(PyExc_TypeError,
3236 "execve(): env.keys() or env.values() is not a list");
3237 goto fail_2;
3238 }
Tim Peters5aa91602002-01-30 05:46:57 +00003239
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003240 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003241 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003242 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003243
3244 key = PyList_GetItem(keys, pos);
3245 val = PyList_GetItem(vals, pos);
3246 if (!key || !val)
3247 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003248
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003249 if (!PyArg_Parse(
3250 key,
3251 "s;execve() arg 3 contains a non-string key",
3252 &k) ||
3253 !PyArg_Parse(
3254 val,
3255 "s;execve() arg 3 contains a non-string value",
3256 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003257 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003258 goto fail_2;
3259 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003260
3261#if defined(PYOS_OS2)
3262 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3263 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3264#endif
Christian Heimes830a4bc2007-11-22 07:43:40 +00003265 len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003266 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003267 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003268 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003269 goto fail_2;
3270 }
Tim Petersc8996f52001-12-03 20:41:00 +00003271 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003272 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003273#if defined(PYOS_OS2)
3274 }
3275#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003276 }
3277 envlist[envc] = 0;
3278
3279 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003280
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003281 /* If we get here it's definitely an error */
3282
3283 (void) posix_error();
3284
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003285 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003286 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00003287 PyMem_DEL(envlist[envc]);
3288 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003289 fail_1:
3290 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003291 Py_XDECREF(vals);
3292 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003293 fail_0:
Martin v. Löwis011e8422009-05-05 04:43:17 +00003294 release_bytes(opath);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003295 return NULL;
3296}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003297#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003298
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003299
Guido van Rossuma1065681999-01-25 23:20:23 +00003300#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003301PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003302"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003303Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003304\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003305 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003306 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003307 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003308
3309static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003310posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003311{
Martin v. Löwis011e8422009-05-05 04:43:17 +00003312 PyObject *opath;
Guido van Rossuma1065681999-01-25 23:20:23 +00003313 char *path;
3314 PyObject *argv;
3315 char **argvlist;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003316 int mode, i;
3317 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00003318 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003319 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003320
3321 /* spawnv has three arguments: (mode, path, argv), where
3322 argv is a list or tuple of strings. */
3323
Martin v. Löwis011e8422009-05-05 04:43:17 +00003324 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
3325 PyUnicode_FSConverter,
3326 &opath, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00003327 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003328 path = bytes2str(opath, 1);
Guido van Rossuma1065681999-01-25 23:20:23 +00003329 if (PyList_Check(argv)) {
3330 argc = PyList_Size(argv);
3331 getitem = PyList_GetItem;
3332 }
3333 else if (PyTuple_Check(argv)) {
3334 argc = PyTuple_Size(argv);
3335 getitem = PyTuple_GetItem;
3336 }
3337 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003338 PyErr_SetString(PyExc_TypeError,
3339 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis011e8422009-05-05 04:43:17 +00003340 release_bytes(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00003341 return NULL;
3342 }
3343
3344 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003345 if (argvlist == NULL) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003346 release_bytes(opath);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003347 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003348 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003349 for (i = 0; i < argc; i++) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003350 if (!fsconvert_strdup((*getitem)(argv, i),
3351 &argvlist[i])) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003352 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003353 PyErr_SetString(
3354 PyExc_TypeError,
3355 "spawnv() arg 2 must contain only strings");
Martin v. Löwis011e8422009-05-05 04:43:17 +00003356 release_bytes(opath);
Fred Drake137507e2000-06-01 02:02:46 +00003357 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003358 }
3359 }
3360 argvlist[argc] = NULL;
3361
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003362#if defined(PYOS_OS2) && defined(PYCC_GCC)
3363 Py_BEGIN_ALLOW_THREADS
3364 spawnval = spawnv(mode, path, argvlist);
3365 Py_END_ALLOW_THREADS
3366#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003367 if (mode == _OLD_P_OVERLAY)
3368 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003369
Tim Peters25059d32001-12-07 20:35:43 +00003370 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003371 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00003372 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003373#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003374
Martin v. Löwis114619e2002-10-07 06:44:21 +00003375 free_string_array(argvlist, argc);
Martin v. Löwis011e8422009-05-05 04:43:17 +00003376 release_bytes(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00003377
Fred Drake699f3522000-06-29 21:12:41 +00003378 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003379 return posix_error();
3380 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003381#if SIZEOF_LONG == SIZEOF_VOID_P
3382 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003383#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003384 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003385#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003386}
3387
3388
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003389PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003390"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003391Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003392\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003393 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003394 path: path of executable file\n\
3395 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003396 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003397
3398static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003399posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003400{
Martin v. Löwis011e8422009-05-05 04:43:17 +00003401 PyObject *opath;
Guido van Rossuma1065681999-01-25 23:20:23 +00003402 char *path;
3403 PyObject *argv, *env;
3404 char **argvlist;
3405 char **envlist;
3406 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003407 int mode, pos, envc;
3408 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00003409 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003410 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00003411 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003412
3413 /* spawnve has four arguments: (mode, path, argv, env), where
3414 argv is a list or tuple of strings and env is a dictionary
3415 like posix.environ. */
3416
Martin v. Löwis011e8422009-05-05 04:43:17 +00003417 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
3418 PyUnicode_FSConverter,
3419 &opath, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00003420 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003421 path = bytes2str(opath, 1);
Guido van Rossuma1065681999-01-25 23:20:23 +00003422 if (PyList_Check(argv)) {
3423 argc = PyList_Size(argv);
3424 getitem = PyList_GetItem;
3425 }
3426 else if (PyTuple_Check(argv)) {
3427 argc = PyTuple_Size(argv);
3428 getitem = PyTuple_GetItem;
3429 }
3430 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003431 PyErr_SetString(PyExc_TypeError,
3432 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003433 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003434 }
3435 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003436 PyErr_SetString(PyExc_TypeError,
3437 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003438 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003439 }
3440
3441 argvlist = PyMem_NEW(char *, argc+1);
3442 if (argvlist == NULL) {
3443 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003444 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003445 }
3446 for (i = 0; i < argc; i++) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003447 if (!fsconvert_strdup((*getitem)(argv, i),
3448 &argvlist[i]))
Guido van Rossuma1065681999-01-25 23:20:23 +00003449 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003450 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00003451 goto fail_1;
3452 }
3453 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003454 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00003455 argvlist[argc] = NULL;
3456
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003457 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003458 if (i < 0)
3459 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003460 envlist = PyMem_NEW(char *, i + 1);
3461 if (envlist == NULL) {
3462 PyErr_NoMemory();
3463 goto fail_1;
3464 }
3465 envc = 0;
3466 keys = PyMapping_Keys(env);
3467 vals = PyMapping_Values(env);
3468 if (!keys || !vals)
3469 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003470 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3471 PyErr_SetString(PyExc_TypeError,
3472 "spawnve(): env.keys() or env.values() is not a list");
3473 goto fail_2;
3474 }
Tim Peters5aa91602002-01-30 05:46:57 +00003475
Guido van Rossuma1065681999-01-25 23:20:23 +00003476 for (pos = 0; pos < i; pos++) {
3477 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003478 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003479
3480 key = PyList_GetItem(keys, pos);
3481 val = PyList_GetItem(vals, pos);
3482 if (!key || !val)
3483 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003484
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003485 if (!PyArg_Parse(
3486 key,
3487 "s;spawnve() arg 3 contains a non-string key",
3488 &k) ||
3489 !PyArg_Parse(
3490 val,
3491 "s;spawnve() arg 3 contains a non-string value",
3492 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00003493 {
3494 goto fail_2;
3495 }
Christian Heimes830a4bc2007-11-22 07:43:40 +00003496 len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003497 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003498 if (p == NULL) {
3499 PyErr_NoMemory();
3500 goto fail_2;
3501 }
Tim Petersc8996f52001-12-03 20:41:00 +00003502 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003503 envlist[envc++] = p;
3504 }
3505 envlist[envc] = 0;
3506
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003507#if defined(PYOS_OS2) && defined(PYCC_GCC)
3508 Py_BEGIN_ALLOW_THREADS
3509 spawnval = spawnve(mode, path, argvlist, envlist);
3510 Py_END_ALLOW_THREADS
3511#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003512 if (mode == _OLD_P_OVERLAY)
3513 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003514
3515 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003516 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003517 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003518#endif
Tim Peters25059d32001-12-07 20:35:43 +00003519
Fred Drake699f3522000-06-29 21:12:41 +00003520 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003521 (void) posix_error();
3522 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003523#if SIZEOF_LONG == SIZEOF_VOID_P
3524 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003525#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003526 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003527#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003528
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003529 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003530 while (--envc >= 0)
3531 PyMem_DEL(envlist[envc]);
3532 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003533 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003534 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003535 Py_XDECREF(vals);
3536 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003537 fail_0:
Martin v. Löwis011e8422009-05-05 04:43:17 +00003538 release_bytes(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00003539 return res;
3540}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003541
3542/* OS/2 supports spawnvp & spawnvpe natively */
3543#if defined(PYOS_OS2)
3544PyDoc_STRVAR(posix_spawnvp__doc__,
3545"spawnvp(mode, file, args)\n\n\
3546Execute the program 'file' in a new process, using the environment\n\
3547search path to find the file.\n\
3548\n\
3549 mode: mode of process creation\n\
3550 file: executable file name\n\
3551 args: tuple or list of strings");
3552
3553static PyObject *
3554posix_spawnvp(PyObject *self, PyObject *args)
3555{
Martin v. Löwis011e8422009-05-05 04:43:17 +00003556 PyObject *opath;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003557 char *path;
3558 PyObject *argv;
3559 char **argvlist;
3560 int mode, i, argc;
3561 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003562 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003563
3564 /* spawnvp has three arguments: (mode, path, argv), where
3565 argv is a list or tuple of strings. */
3566
Martin v. Löwis011e8422009-05-05 04:43:17 +00003567 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
3568 PyUnicode_FSConverter,
3569 &opath, &argv))
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003570 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003571 path = bytes2str(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003572 if (PyList_Check(argv)) {
3573 argc = PyList_Size(argv);
3574 getitem = PyList_GetItem;
3575 }
3576 else if (PyTuple_Check(argv)) {
3577 argc = PyTuple_Size(argv);
3578 getitem = PyTuple_GetItem;
3579 }
3580 else {
3581 PyErr_SetString(PyExc_TypeError,
3582 "spawnvp() arg 2 must be a tuple or list");
Martin v. Löwis011e8422009-05-05 04:43:17 +00003583 release_bytes(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003584 return NULL;
3585 }
3586
3587 argvlist = PyMem_NEW(char *, argc+1);
3588 if (argvlist == NULL) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003589 release_bytes(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003590 return PyErr_NoMemory();
3591 }
3592 for (i = 0; i < argc; i++) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003593 if (!fsconvert_strdup((*getitem)(argv, i),
3594 &argvlist[i])) {
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003595 free_string_array(argvlist, i);
3596 PyErr_SetString(
3597 PyExc_TypeError,
3598 "spawnvp() arg 2 must contain only strings");
Martin v. Löwis011e8422009-05-05 04:43:17 +00003599 release_bytes(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003600 return NULL;
3601 }
3602 }
3603 argvlist[argc] = NULL;
3604
3605 Py_BEGIN_ALLOW_THREADS
3606#if defined(PYCC_GCC)
3607 spawnval = spawnvp(mode, path, argvlist);
3608#else
3609 spawnval = _spawnvp(mode, path, argvlist);
3610#endif
3611 Py_END_ALLOW_THREADS
3612
3613 free_string_array(argvlist, argc);
Martin v. Löwis011e8422009-05-05 04:43:17 +00003614 release_bytes(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003615
3616 if (spawnval == -1)
3617 return posix_error();
3618 else
3619 return Py_BuildValue("l", (long) spawnval);
3620}
3621
3622
3623PyDoc_STRVAR(posix_spawnvpe__doc__,
3624"spawnvpe(mode, file, args, env)\n\n\
3625Execute the program 'file' in a new process, using the environment\n\
3626search path to find the file.\n\
3627\n\
3628 mode: mode of process creation\n\
3629 file: executable file name\n\
3630 args: tuple or list of arguments\n\
3631 env: dictionary of strings mapping to strings");
3632
3633static PyObject *
3634posix_spawnvpe(PyObject *self, PyObject *args)
3635{
Martin v. Löwis011e8422009-05-05 04:43:17 +00003636 PyObject *opath
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003637 char *path;
3638 PyObject *argv, *env;
3639 char **argvlist;
3640 char **envlist;
3641 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3642 int mode, i, pos, argc, envc;
3643 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003644 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003645 int lastarg = 0;
3646
3647 /* spawnvpe has four arguments: (mode, path, argv, env), where
3648 argv is a list or tuple of strings and env is a dictionary
3649 like posix.environ. */
3650
3651 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
Martin v. Löwis011e8422009-05-05 04:43:17 +00003652 PyUnicode_FSConverter,
3653 &opath, &argv, &env))
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003654 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003655 path = bytes2str(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003656 if (PyList_Check(argv)) {
3657 argc = PyList_Size(argv);
3658 getitem = PyList_GetItem;
3659 }
3660 else if (PyTuple_Check(argv)) {
3661 argc = PyTuple_Size(argv);
3662 getitem = PyTuple_GetItem;
3663 }
3664 else {
3665 PyErr_SetString(PyExc_TypeError,
3666 "spawnvpe() arg 2 must be a tuple or list");
3667 goto fail_0;
3668 }
3669 if (!PyMapping_Check(env)) {
3670 PyErr_SetString(PyExc_TypeError,
3671 "spawnvpe() arg 3 must be a mapping object");
3672 goto fail_0;
3673 }
3674
3675 argvlist = PyMem_NEW(char *, argc+1);
3676 if (argvlist == NULL) {
3677 PyErr_NoMemory();
3678 goto fail_0;
3679 }
3680 for (i = 0; i < argc; i++) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003681 if (!fsconvert_strdup((*getitem)(argv, i),
3682 &argvlist[i]))
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003683 {
3684 lastarg = i;
3685 goto fail_1;
3686 }
3687 }
3688 lastarg = argc;
3689 argvlist[argc] = NULL;
3690
3691 i = PyMapping_Size(env);
3692 if (i < 0)
3693 goto fail_1;
3694 envlist = PyMem_NEW(char *, i + 1);
3695 if (envlist == NULL) {
3696 PyErr_NoMemory();
3697 goto fail_1;
3698 }
3699 envc = 0;
3700 keys = PyMapping_Keys(env);
3701 vals = PyMapping_Values(env);
3702 if (!keys || !vals)
3703 goto fail_2;
3704 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3705 PyErr_SetString(PyExc_TypeError,
3706 "spawnvpe(): env.keys() or env.values() is not a list");
3707 goto fail_2;
3708 }
3709
3710 for (pos = 0; pos < i; pos++) {
3711 char *p, *k, *v;
3712 size_t len;
3713
3714 key = PyList_GetItem(keys, pos);
3715 val = PyList_GetItem(vals, pos);
3716 if (!key || !val)
3717 goto fail_2;
3718
3719 if (!PyArg_Parse(
3720 key,
3721 "s;spawnvpe() arg 3 contains a non-string key",
3722 &k) ||
3723 !PyArg_Parse(
3724 val,
3725 "s;spawnvpe() arg 3 contains a non-string value",
3726 &v))
3727 {
3728 goto fail_2;
3729 }
Christian Heimes830a4bc2007-11-22 07:43:40 +00003730 len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003731 p = PyMem_NEW(char, len);
3732 if (p == NULL) {
3733 PyErr_NoMemory();
3734 goto fail_2;
3735 }
3736 PyOS_snprintf(p, len, "%s=%s", k, v);
3737 envlist[envc++] = p;
3738 }
3739 envlist[envc] = 0;
3740
3741 Py_BEGIN_ALLOW_THREADS
3742#if defined(PYCC_GCC)
Christian Heimes292d3512008-02-03 16:51:08 +00003743 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003744#else
Christian Heimes292d3512008-02-03 16:51:08 +00003745 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003746#endif
3747 Py_END_ALLOW_THREADS
3748
3749 if (spawnval == -1)
3750 (void) posix_error();
3751 else
3752 res = Py_BuildValue("l", (long) spawnval);
3753
3754 fail_2:
3755 while (--envc >= 0)
3756 PyMem_DEL(envlist[envc]);
3757 PyMem_DEL(envlist);
3758 fail_1:
3759 free_string_array(argvlist, lastarg);
3760 Py_XDECREF(vals);
3761 Py_XDECREF(keys);
3762 fail_0:
Martin v. Löwis011e8422009-05-05 04:43:17 +00003763 release_bytes(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003764 return res;
3765}
3766#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003767#endif /* HAVE_SPAWNV */
3768
3769
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003770#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003771PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003772"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003773Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3774\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003775Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003776
3777static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003778posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003779{
Christian Heimes400adb02008-02-01 08:12:03 +00003780 pid_t pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003781 if (pid == -1)
3782 return posix_error();
Georg Brandl2ee470f2008-07-16 12:55:28 +00003783 if (pid == 0)
3784 PyOS_AfterFork();
Antoine Pitrouc3ee1662009-05-23 16:02:33 +00003785 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003786}
3787#endif
3788
3789
Guido van Rossumad0ee831995-03-01 10:34:45 +00003790#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003791PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003792"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003793Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003794Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003795
Barry Warsaw53699e91996-12-10 23:23:01 +00003796static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003797posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003798{
Christian Heimes400adb02008-02-01 08:12:03 +00003799 pid_t pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003800 if (pid == -1)
3801 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003802 if (pid == 0)
3803 PyOS_AfterFork();
Antoine Pitrouc3ee1662009-05-23 16:02:33 +00003804 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003805}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003806#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003807
Neal Norwitzb59798b2003-03-21 01:43:31 +00003808/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003809/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3810#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003811#define DEV_PTY_FILE "/dev/ptc"
3812#define HAVE_DEV_PTMX
3813#else
3814#define DEV_PTY_FILE "/dev/ptmx"
3815#endif
3816
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003817#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003818#ifdef HAVE_PTY_H
3819#include <pty.h>
3820#else
3821#ifdef HAVE_LIBUTIL_H
3822#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003823#endif /* HAVE_LIBUTIL_H */
3824#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003825#ifdef HAVE_STROPTS_H
3826#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003827#endif
3828#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003829
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003830#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003831PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003832"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003833Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003834
3835static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003836posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003837{
3838 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003839#ifndef HAVE_OPENPTY
3840 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003841#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003842#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003843 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003844#ifdef sun
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003845 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003846#endif
3847#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003848
Thomas Wouters70c21a12000-07-14 14:28:33 +00003849#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003850 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3851 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003852#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003853 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3854 if (slave_name == NULL)
3855 return posix_error();
3856
3857 slave_fd = open(slave_name, O_RDWR);
3858 if (slave_fd < 0)
3859 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003860#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003861 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003862 if (master_fd < 0)
3863 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003864 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003865 /* change permission of slave */
3866 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003867 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003868 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003869 }
3870 /* unlock slave */
3871 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003872 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003873 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003874 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003875 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003876 slave_name = ptsname(master_fd); /* get name of slave */
3877 if (slave_name == NULL)
3878 return posix_error();
3879 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3880 if (slave_fd < 0)
3881 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003882#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003883 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3884 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003885#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003886 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003887#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003888#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003889#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003890
Fred Drake8cef4cf2000-06-28 16:40:38 +00003891 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003892
Fred Drake8cef4cf2000-06-28 16:40:38 +00003893}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003894#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003895
3896#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003897PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003898"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003899Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3900Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003901To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003902
3903static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003904posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003905{
Christian Heimes400adb02008-02-01 08:12:03 +00003906 int master_fd = -1;
3907 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003908
Fred Drake8cef4cf2000-06-28 16:40:38 +00003909 pid = forkpty(&master_fd, NULL, NULL, NULL);
3910 if (pid == -1)
3911 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003912 if (pid == 0)
3913 PyOS_AfterFork();
Antoine Pitrouc3ee1662009-05-23 16:02:33 +00003914 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00003915}
3916#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003917
Guido van Rossumad0ee831995-03-01 10:34:45 +00003918#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003919PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003920"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003921Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003922
Barry Warsaw53699e91996-12-10 23:23:01 +00003923static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003924posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003925{
Christian Heimes217cfd12007-12-02 14:31:20 +00003926 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003927}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003928#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003929
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003930
Guido van Rossumad0ee831995-03-01 10:34:45 +00003931#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003932PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003933"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003934Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003935
Barry Warsaw53699e91996-12-10 23:23:01 +00003936static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003937posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003938{
Christian Heimes217cfd12007-12-02 14:31:20 +00003939 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003940}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003941#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003942
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003943
Guido van Rossumad0ee831995-03-01 10:34:45 +00003944#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003945PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003946"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003947Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003948
Barry Warsaw53699e91996-12-10 23:23:01 +00003949static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003950posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003951{
Christian Heimes217cfd12007-12-02 14:31:20 +00003952 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003953}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003954#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003955
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003956
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003957PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003958"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003959Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003960
Barry Warsaw53699e91996-12-10 23:23:01 +00003961static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003962posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003963{
Antoine Pitrou971e51b2009-05-23 16:14:27 +00003964 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003965}
3966
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003967
Fred Drakec9680921999-12-13 16:37:25 +00003968#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003969PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003970"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003971Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003972
3973static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003974posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003975{
3976 PyObject *result = NULL;
3977
Fred Drakec9680921999-12-13 16:37:25 +00003978#ifdef NGROUPS_MAX
3979#define MAX_GROUPS NGROUPS_MAX
3980#else
3981 /* defined to be 16 on Solaris7, so this should be a small number */
3982#define MAX_GROUPS 64
3983#endif
3984 gid_t grouplist[MAX_GROUPS];
3985 int n;
3986
3987 n = getgroups(MAX_GROUPS, grouplist);
3988 if (n < 0)
3989 posix_error();
3990 else {
3991 result = PyList_New(n);
3992 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003993 int i;
3994 for (i = 0; i < n; ++i) {
Christian Heimes217cfd12007-12-02 14:31:20 +00003995 PyObject *o = PyLong_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003996 if (o == NULL) {
3997 Py_DECREF(result);
3998 result = NULL;
3999 break;
4000 }
4001 PyList_SET_ITEM(result, i, o);
4002 }
4003 }
4004 }
Neal Norwitze241ce82003-02-17 18:17:05 +00004005
Fred Drakec9680921999-12-13 16:37:25 +00004006 return result;
4007}
4008#endif
4009
Martin v. Löwis606edc12002-06-13 21:09:11 +00004010#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004011PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004012"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004013Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00004014
4015static PyObject *
4016posix_getpgid(PyObject *self, PyObject *args)
4017{
Antoine Pitrou971e51b2009-05-23 16:14:27 +00004018 pid_t pid, pgid;
4019 if (!PyArg_ParseTuple(args, PARSE_PID ":getpgid", &pid))
Martin v. Löwis606edc12002-06-13 21:09:11 +00004020 return NULL;
4021 pgid = getpgid(pid);
4022 if (pgid < 0)
4023 return posix_error();
Antoine Pitrou971e51b2009-05-23 16:14:27 +00004024 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004025}
4026#endif /* HAVE_GETPGID */
4027
4028
Guido van Rossumb6775db1994-08-01 11:34:53 +00004029#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004030PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004031"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004032Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004033
Barry Warsaw53699e91996-12-10 23:23:01 +00004034static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004035posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004036{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004037#ifdef GETPGRP_HAVE_ARG
Antoine Pitrou971e51b2009-05-23 16:14:27 +00004038 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004039#else /* GETPGRP_HAVE_ARG */
Antoine Pitrou971e51b2009-05-23 16:14:27 +00004040 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004041#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004042}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004043#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004044
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004045
Guido van Rossumb6775db1994-08-01 11:34:53 +00004046#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004047PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004048"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004049Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004050
Barry Warsaw53699e91996-12-10 23:23:01 +00004051static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004052posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004053{
Guido van Rossum64933891994-10-20 21:56:42 +00004054#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00004055 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004056#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004057 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004058#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00004059 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004060 Py_INCREF(Py_None);
4061 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004062}
4063
Guido van Rossumb6775db1994-08-01 11:34:53 +00004064#endif /* HAVE_SETPGRP */
4065
Guido van Rossumad0ee831995-03-01 10:34:45 +00004066#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004067PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004068"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004069Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004070
Barry Warsaw53699e91996-12-10 23:23:01 +00004071static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004072posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004073{
Antoine Pitrou971e51b2009-05-23 16:14:27 +00004074 return PyLong_FromPid(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004075}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004076#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004077
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004078
Fred Drake12c6e2d1999-12-14 21:25:03 +00004079#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004080PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004081"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004082Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004083
4084static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004085posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004086{
Neal Norwitze241ce82003-02-17 18:17:05 +00004087 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00004088 char *name;
4089 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004090
Fred Drakea30680b2000-12-06 21:24:28 +00004091 errno = 0;
4092 name = getlogin();
4093 if (name == NULL) {
4094 if (errno)
4095 posix_error();
4096 else
4097 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00004098 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00004099 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00004100 else
Neal Norwitz93c56822007-08-26 07:10:06 +00004101 result = PyUnicode_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00004102 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004103
Fred Drake12c6e2d1999-12-14 21:25:03 +00004104 return result;
4105}
4106#endif
4107
Guido van Rossumad0ee831995-03-01 10:34:45 +00004108#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004109PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004110"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004111Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004112
Barry Warsaw53699e91996-12-10 23:23:01 +00004113static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004114posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004115{
Christian Heimes217cfd12007-12-02 14:31:20 +00004116 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004117}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004118#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004119
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004120
Guido van Rossumad0ee831995-03-01 10:34:45 +00004121#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004122PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004123"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004124Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004125
Barry Warsaw53699e91996-12-10 23:23:01 +00004126static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004127posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004128{
Christian Heimes292d3512008-02-03 16:51:08 +00004129 pid_t pid;
4130 int sig;
Antoine Pitrouc3ee1662009-05-23 16:02:33 +00004131 if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00004132 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004133#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004134 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4135 APIRET rc;
4136 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004137 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004138
4139 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4140 APIRET rc;
4141 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004142 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004143
4144 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004145 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004146#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00004147 if (kill(pid, sig) == -1)
4148 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004149#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004150 Py_INCREF(Py_None);
4151 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004152}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004153#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004154
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004155#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004156PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004157"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004158Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004159
4160static PyObject *
4161posix_killpg(PyObject *self, PyObject *args)
4162{
Antoine Pitrou971e51b2009-05-23 16:14:27 +00004163 int sig;
4164 pid_t pgid;
4165 /* XXX some man pages make the `pgid` parameter an int, others
4166 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4167 take the same type. Moreover, pid_t is always at least as wide as
4168 int (else compilation of this module fails), which is safe. */
4169 if (!PyArg_ParseTuple(args, PARSE_PID "i:killpg", &pgid, &sig))
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004170 return NULL;
4171 if (killpg(pgid, sig) == -1)
4172 return posix_error();
4173 Py_INCREF(Py_None);
4174 return Py_None;
4175}
4176#endif
4177
Guido van Rossumc0125471996-06-28 18:55:32 +00004178#ifdef HAVE_PLOCK
4179
4180#ifdef HAVE_SYS_LOCK_H
4181#include <sys/lock.h>
4182#endif
4183
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004184PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004185"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004186Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004187
Barry Warsaw53699e91996-12-10 23:23:01 +00004188static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004189posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004190{
4191 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004192 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00004193 return NULL;
4194 if (plock(op) == -1)
4195 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004196 Py_INCREF(Py_None);
4197 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004198}
4199#endif
4200
Guido van Rossumb6775db1994-08-01 11:34:53 +00004201#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004202PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004203"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004204Set the current process's user id.");
4205
Barry Warsaw53699e91996-12-10 23:23:01 +00004206static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004207posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004208{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004209 long uid_arg;
4210 uid_t uid;
4211 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004212 return NULL;
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004213 uid = uid_arg;
4214 if (uid != uid_arg) {
4215 PyErr_SetString(PyExc_OverflowError, "user id too big");
4216 return NULL;
4217 }
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004218 if (setuid(uid) < 0)
4219 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004220 Py_INCREF(Py_None);
4221 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004222}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004223#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004224
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004225
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004226#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004227PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004228"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004229Set the current process's effective user id.");
4230
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004231static PyObject *
4232posix_seteuid (PyObject *self, PyObject *args)
4233{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004234 long euid_arg;
4235 uid_t euid;
4236 if (!PyArg_ParseTuple(args, "l", &euid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004237 return NULL;
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004238 euid = euid_arg;
4239 if (euid != euid_arg) {
4240 PyErr_SetString(PyExc_OverflowError, "user id too big");
4241 return NULL;
4242 }
4243 if (seteuid(euid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004244 return posix_error();
4245 } else {
4246 Py_INCREF(Py_None);
4247 return Py_None;
4248 }
4249}
4250#endif /* HAVE_SETEUID */
4251
4252#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004253PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004254"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004255Set the current process's effective group id.");
4256
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004257static PyObject *
4258posix_setegid (PyObject *self, PyObject *args)
4259{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004260 long egid_arg;
4261 gid_t egid;
4262 if (!PyArg_ParseTuple(args, "l", &egid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004263 return NULL;
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004264 egid = egid_arg;
4265 if (egid != egid_arg) {
4266 PyErr_SetString(PyExc_OverflowError, "group id too big");
4267 return NULL;
4268 }
4269 if (setegid(egid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004270 return posix_error();
4271 } else {
4272 Py_INCREF(Py_None);
4273 return Py_None;
4274 }
4275}
4276#endif /* HAVE_SETEGID */
4277
4278#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004279PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004280"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004281Set the current process's real and effective user ids.");
4282
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004283static PyObject *
4284posix_setreuid (PyObject *self, PyObject *args)
4285{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004286 long ruid_arg, euid_arg;
4287 uid_t ruid, euid;
4288 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004289 return NULL;
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004290 ruid = ruid_arg;
4291 euid = euid_arg;
4292 if (euid != euid_arg || ruid != ruid_arg) {
4293 PyErr_SetString(PyExc_OverflowError, "user id too big");
4294 return NULL;
4295 }
4296 if (setreuid(ruid, euid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004297 return posix_error();
4298 } else {
4299 Py_INCREF(Py_None);
4300 return Py_None;
4301 }
4302}
4303#endif /* HAVE_SETREUID */
4304
4305#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004306PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004307"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004308Set the current process's real and effective group ids.");
4309
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004310static PyObject *
4311posix_setregid (PyObject *self, PyObject *args)
4312{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004313 long rgid_arg, egid_arg;
4314 gid_t rgid, egid;
4315 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004316 return NULL;
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004317 rgid = rgid_arg;
4318 egid = egid_arg;
4319 if (egid != egid_arg || rgid != rgid_arg) {
4320 PyErr_SetString(PyExc_OverflowError, "group id too big");
4321 return NULL;
4322 }
4323 if (setregid(rgid, egid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004324 return posix_error();
4325 } else {
4326 Py_INCREF(Py_None);
4327 return Py_None;
4328 }
4329}
4330#endif /* HAVE_SETREGID */
4331
Guido van Rossumb6775db1994-08-01 11:34:53 +00004332#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004333PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004334"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004335Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004336
Barry Warsaw53699e91996-12-10 23:23:01 +00004337static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004338posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004339{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004340 long gid_arg;
4341 gid_t gid;
4342 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004343 return NULL;
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004344 gid = gid_arg;
4345 if (gid != gid_arg) {
4346 PyErr_SetString(PyExc_OverflowError, "group id too big");
4347 return NULL;
4348 }
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004349 if (setgid(gid) < 0)
4350 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004351 Py_INCREF(Py_None);
4352 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004353}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004354#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004355
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004356#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004357PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004358"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004359Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004360
4361static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004362posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004363{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004364 int i, len;
4365 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004366
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004367 if (!PySequence_Check(groups)) {
4368 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4369 return NULL;
4370 }
4371 len = PySequence_Size(groups);
4372 if (len > MAX_GROUPS) {
4373 PyErr_SetString(PyExc_ValueError, "too many groups");
4374 return NULL;
4375 }
4376 for(i = 0; i < len; i++) {
4377 PyObject *elem;
4378 elem = PySequence_GetItem(groups, i);
4379 if (!elem)
4380 return NULL;
Guido van Rossumddefaf32007-01-14 03:31:43 +00004381 if (!PyLong_Check(elem)) {
4382 PyErr_SetString(PyExc_TypeError,
4383 "groups must be integers");
4384 Py_DECREF(elem);
4385 return NULL;
4386 } else {
4387 unsigned long x = PyLong_AsUnsignedLong(elem);
4388 if (PyErr_Occurred()) {
4389 PyErr_SetString(PyExc_TypeError,
4390 "group id too big");
Georg Brandla13c2442005-11-22 19:30:31 +00004391 Py_DECREF(elem);
4392 return NULL;
Georg Brandla13c2442005-11-22 19:30:31 +00004393 }
Georg Brandla13c2442005-11-22 19:30:31 +00004394 grouplist[i] = x;
Guido van Rossumddefaf32007-01-14 03:31:43 +00004395 /* read back the value to see if it fitted in gid_t */
Georg Brandla13c2442005-11-22 19:30:31 +00004396 if (grouplist[i] != x) {
4397 PyErr_SetString(PyExc_TypeError,
4398 "group id too big");
4399 Py_DECREF(elem);
4400 return NULL;
4401 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004402 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004403 Py_DECREF(elem);
4404 }
4405
4406 if (setgroups(len, grouplist) < 0)
4407 return posix_error();
4408 Py_INCREF(Py_None);
4409 return Py_None;
4410}
4411#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004412
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004413#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4414static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00004415wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004416{
4417 PyObject *result;
4418 static PyObject *struct_rusage;
4419
4420 if (pid == -1)
4421 return posix_error();
4422
4423 if (struct_rusage == NULL) {
Christian Heimes072c0f12008-01-03 23:01:04 +00004424 PyObject *m = PyImport_ImportModuleNoBlock("resource");
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004425 if (m == NULL)
4426 return NULL;
4427 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4428 Py_DECREF(m);
4429 if (struct_rusage == NULL)
4430 return NULL;
4431 }
4432
4433 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4434 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4435 if (!result)
4436 return NULL;
4437
4438#ifndef doubletime
4439#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4440#endif
4441
4442 PyStructSequence_SET_ITEM(result, 0,
4443 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4444 PyStructSequence_SET_ITEM(result, 1,
4445 PyFloat_FromDouble(doubletime(ru->ru_stime)));
4446#define SET_INT(result, index, value)\
Christian Heimes217cfd12007-12-02 14:31:20 +00004447 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004448 SET_INT(result, 2, ru->ru_maxrss);
4449 SET_INT(result, 3, ru->ru_ixrss);
4450 SET_INT(result, 4, ru->ru_idrss);
4451 SET_INT(result, 5, ru->ru_isrss);
4452 SET_INT(result, 6, ru->ru_minflt);
4453 SET_INT(result, 7, ru->ru_majflt);
4454 SET_INT(result, 8, ru->ru_nswap);
4455 SET_INT(result, 9, ru->ru_inblock);
4456 SET_INT(result, 10, ru->ru_oublock);
4457 SET_INT(result, 11, ru->ru_msgsnd);
4458 SET_INT(result, 12, ru->ru_msgrcv);
4459 SET_INT(result, 13, ru->ru_nsignals);
4460 SET_INT(result, 14, ru->ru_nvcsw);
4461 SET_INT(result, 15, ru->ru_nivcsw);
4462#undef SET_INT
4463
4464 if (PyErr_Occurred()) {
4465 Py_DECREF(result);
4466 return NULL;
4467 }
4468
Antoine Pitrouc3ee1662009-05-23 16:02:33 +00004469 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004470}
4471#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4472
4473#ifdef HAVE_WAIT3
4474PyDoc_STRVAR(posix_wait3__doc__,
4475"wait3(options) -> (pid, status, rusage)\n\n\
4476Wait for completion of a child process.");
4477
4478static PyObject *
4479posix_wait3(PyObject *self, PyObject *args)
4480{
Christian Heimes292d3512008-02-03 16:51:08 +00004481 pid_t pid;
4482 int options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004483 struct rusage ru;
4484 WAIT_TYPE status;
4485 WAIT_STATUS_INT(status) = 0;
4486
4487 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4488 return NULL;
4489
4490 Py_BEGIN_ALLOW_THREADS
4491 pid = wait3(&status, options, &ru);
4492 Py_END_ALLOW_THREADS
4493
4494 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
4495}
4496#endif /* HAVE_WAIT3 */
4497
4498#ifdef HAVE_WAIT4
4499PyDoc_STRVAR(posix_wait4__doc__,
4500"wait4(pid, options) -> (pid, status, rusage)\n\n\
4501Wait for completion of a given child process.");
4502
4503static PyObject *
4504posix_wait4(PyObject *self, PyObject *args)
4505{
Christian Heimes292d3512008-02-03 16:51:08 +00004506 pid_t pid;
4507 int options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004508 struct rusage ru;
4509 WAIT_TYPE status;
4510 WAIT_STATUS_INT(status) = 0;
4511
Antoine Pitrouc3ee1662009-05-23 16:02:33 +00004512 if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004513 return NULL;
4514
4515 Py_BEGIN_ALLOW_THREADS
4516 pid = wait4(pid, &status, options, &ru);
4517 Py_END_ALLOW_THREADS
4518
4519 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
4520}
4521#endif /* HAVE_WAIT4 */
4522
Guido van Rossumb6775db1994-08-01 11:34:53 +00004523#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004524PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004525"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004526Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004527
Barry Warsaw53699e91996-12-10 23:23:01 +00004528static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004529posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004530{
Christian Heimes292d3512008-02-03 16:51:08 +00004531 pid_t pid;
4532 int options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004533 WAIT_TYPE status;
4534 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004535
Antoine Pitrouc3ee1662009-05-23 16:02:33 +00004536 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004537 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004538 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004539 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004540 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004541 if (pid == -1)
4542 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004543
Antoine Pitrouc3ee1662009-05-23 16:02:33 +00004544 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00004545}
4546
Tim Petersab034fa2002-02-01 11:27:43 +00004547#elif defined(HAVE_CWAIT)
4548
4549/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004550PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004551"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004552"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004553
4554static PyObject *
4555posix_waitpid(PyObject *self, PyObject *args)
4556{
Thomas Wouters477c8d52006-05-27 19:21:47 +00004557 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004558 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00004559
Antoine Pitrouc3ee1662009-05-23 16:02:33 +00004560 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
Tim Petersab034fa2002-02-01 11:27:43 +00004561 return NULL;
4562 Py_BEGIN_ALLOW_THREADS
4563 pid = _cwait(&status, pid, options);
4564 Py_END_ALLOW_THREADS
4565 if (pid == -1)
4566 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004567
4568 /* shift the status left a byte so this is more like the POSIX waitpid */
Antoine Pitrouc3ee1662009-05-23 16:02:33 +00004569 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00004570}
4571#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004572
Guido van Rossumad0ee831995-03-01 10:34:45 +00004573#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004574PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004575"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004576Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004577
Barry Warsaw53699e91996-12-10 23:23:01 +00004578static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004579posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004580{
Christian Heimes292d3512008-02-03 16:51:08 +00004581 pid_t pid;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004582 WAIT_TYPE status;
4583 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00004584
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004585 Py_BEGIN_ALLOW_THREADS
4586 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004587 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004588 if (pid == -1)
4589 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004590
Antoine Pitrouc3ee1662009-05-23 16:02:33 +00004591 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00004592}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004593#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004594
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004595
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004596PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004597"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004598Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004599
Barry Warsaw53699e91996-12-10 23:23:01 +00004600static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004601posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004602{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004603#ifdef HAVE_LSTAT
Martin v. Löwis011e8422009-05-05 04:43:17 +00004604 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004605#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004606#ifdef MS_WINDOWS
Martin v. Löwis011e8422009-05-05 04:43:17 +00004607 return posix_do_stat(self, args, "O&:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004608#else
Martin v. Löwis011e8422009-05-05 04:43:17 +00004609 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004610#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004611#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004612}
4613
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004614
Guido van Rossumb6775db1994-08-01 11:34:53 +00004615#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004616PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004617"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004618Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004619
Barry Warsaw53699e91996-12-10 23:23:01 +00004620static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004621posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004622{
Thomas Wouters89f507f2006-12-13 04:49:30 +00004623 PyObject* v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00004624 char buf[MAXPATHLEN];
Martin v. Löwis011e8422009-05-05 04:43:17 +00004625 PyObject *opath;
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004626 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004627 int n;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004628 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004629
Martin v. Löwis011e8422009-05-05 04:43:17 +00004630 if (!PyArg_ParseTuple(args, "O&:readlink",
4631 PyUnicode_FSConverter, &opath))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004632 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004633 path = bytes2str(opath, 1);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004634 v = PySequence_GetItem(args, 0);
Neal Norwitzcda5c062007-08-12 17:09:36 +00004635 if (v == NULL) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00004636 release_bytes(opath);
Neal Norwitzcda5c062007-08-12 17:09:36 +00004637 return NULL;
4638 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00004639
4640 if (PyUnicode_Check(v)) {
4641 arg_is_unicode = 1;
4642 }
4643 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004644
Barry Warsaw53699e91996-12-10 23:23:01 +00004645 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004646 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004647 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004648 if (n < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004649 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004650
Martin v. Löwis011e8422009-05-05 04:43:17 +00004651 release_bytes(opath);
Christian Heimes72b710a2008-05-26 13:28:38 +00004652 v = PyBytes_FromStringAndSize(buf, n);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004653 if (arg_is_unicode) {
4654 PyObject *w;
4655
4656 w = PyUnicode_FromEncodedObject(v,
4657 Py_FileSystemDefaultEncoding,
Martin v. Löwis43c57782009-05-10 08:15:24 +00004658 "surrogateescape");
Thomas Wouters89f507f2006-12-13 04:49:30 +00004659 if (w != NULL) {
4660 Py_DECREF(v);
4661 v = w;
4662 }
4663 else {
Guido van Rossumf0af3e32008-10-02 18:55:37 +00004664 v = NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004665 }
4666 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00004667 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004668}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004669#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004670
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004671
Guido van Rossumb6775db1994-08-01 11:34:53 +00004672#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004673PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004674"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00004675Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004676
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004677static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004678posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004679{
Martin v. Löwis011e8422009-05-05 04:43:17 +00004680 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004681}
4682#endif /* HAVE_SYMLINK */
4683
4684
4685#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00004686#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4687static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004688system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004689{
4690 ULONG value = 0;
4691
4692 Py_BEGIN_ALLOW_THREADS
4693 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4694 Py_END_ALLOW_THREADS
4695
4696 return value;
4697}
4698
4699static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004700posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004701{
Guido van Rossumd48f2521997-12-05 22:19:34 +00004702 /* Currently Only Uptime is Provided -- Others Later */
4703 return Py_BuildValue("ddddd",
4704 (double)0 /* t.tms_utime / HZ */,
4705 (double)0 /* t.tms_stime / HZ */,
4706 (double)0 /* t.tms_cutime / HZ */,
4707 (double)0 /* t.tms_cstime / HZ */,
4708 (double)system_uptime() / 1000);
4709}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004710#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00004711#define NEED_TICKS_PER_SECOND
4712static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00004713static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004714posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004715{
4716 struct tms t;
4717 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00004718 errno = 0;
4719 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004720 if (c == (clock_t) -1)
4721 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004722 return Py_BuildValue("ddddd",
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00004723 (double)t.tms_utime / ticks_per_second,
4724 (double)t.tms_stime / ticks_per_second,
4725 (double)t.tms_cutime / ticks_per_second,
4726 (double)t.tms_cstime / ticks_per_second,
4727 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004728}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004729#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004730#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004731
4732
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004733#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004734#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004735static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004736posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004737{
4738 FILETIME create, exit, kernel, user;
4739 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004740 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004741 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4742 /* The fields of a FILETIME structure are the hi and lo part
4743 of a 64-bit value expressed in 100 nanosecond units.
4744 1e7 is one second in such units; 1e-7 the inverse.
4745 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4746 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004747 return Py_BuildValue(
4748 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004749 (double)(user.dwHighDateTime*429.4967296 +
4750 user.dwLowDateTime*1e-7),
Christian Heimes68f5fbe2008-02-14 08:27:37 +00004751 (double)(kernel.dwHighDateTime*429.4967296 +
4752 kernel.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004753 (double)0,
4754 (double)0,
4755 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004756}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004757#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004758
4759#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004760PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004761"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004762Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004763#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004764
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004765
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004766#ifdef HAVE_GETSID
4767PyDoc_STRVAR(posix_getsid__doc__,
4768"getsid(pid) -> sid\n\n\
4769Call the system call getsid().");
4770
4771static PyObject *
4772posix_getsid(PyObject *self, PyObject *args)
4773{
Christian Heimes292d3512008-02-03 16:51:08 +00004774 pid_t pid;
4775 int sid;
Antoine Pitrouc3ee1662009-05-23 16:02:33 +00004776 if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004777 return NULL;
4778 sid = getsid(pid);
4779 if (sid < 0)
4780 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00004781 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004782}
4783#endif /* HAVE_GETSID */
4784
4785
Guido van Rossumb6775db1994-08-01 11:34:53 +00004786#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004787PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004788"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004789Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004790
Barry Warsaw53699e91996-12-10 23:23:01 +00004791static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004792posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004793{
Guido van Rossum687dd131993-05-17 08:34:16 +00004794 if (setsid() < 0)
4795 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004796 Py_INCREF(Py_None);
4797 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004798}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004799#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004800
Guido van Rossumb6775db1994-08-01 11:34:53 +00004801#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004802PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004803"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004804Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004805
Barry Warsaw53699e91996-12-10 23:23:01 +00004806static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004807posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004808{
Christian Heimes292d3512008-02-03 16:51:08 +00004809 pid_t pid;
4810 int pgrp;
Antoine Pitrouc3ee1662009-05-23 16:02:33 +00004811 if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004812 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004813 if (setpgid(pid, pgrp) < 0)
4814 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004815 Py_INCREF(Py_None);
4816 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004817}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004818#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004819
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004820
Guido van Rossumb6775db1994-08-01 11:34:53 +00004821#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004822PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004823"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004824Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004825
Barry Warsaw53699e91996-12-10 23:23:01 +00004826static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004827posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004828{
Christian Heimes15ebc882008-02-04 18:48:49 +00004829 int fd;
4830 pid_t pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004831 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004832 return NULL;
4833 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004834 if (pgid < 0)
4835 return posix_error();
Antoine Pitrouc3ee1662009-05-23 16:02:33 +00004836 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004837}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004838#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004839
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004840
Guido van Rossumb6775db1994-08-01 11:34:53 +00004841#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004842PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004843"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004844Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004845
Barry Warsaw53699e91996-12-10 23:23:01 +00004846static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004847posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004848{
Antoine Pitrou971e51b2009-05-23 16:14:27 +00004849 int fd;
4850 pid_t pgid;
4851 if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004852 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004853 if (tcsetpgrp(fd, pgid) < 0)
4854 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004855 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004856 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004857}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004858#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004859
Guido van Rossum687dd131993-05-17 08:34:16 +00004860/* Functions acting on file descriptors */
4861
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004862PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004863"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004864Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004865
Barry Warsaw53699e91996-12-10 23:23:01 +00004866static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004867posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004868{
Martin v. Löwis011e8422009-05-05 04:43:17 +00004869 PyObject *ofile;
4870 char *file;
Guido van Rossum687dd131993-05-17 08:34:16 +00004871 int flag;
4872 int mode = 0777;
4873 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004874
4875#ifdef MS_WINDOWS
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00004876 PyUnicodeObject *po;
4877 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4878 Py_BEGIN_ALLOW_THREADS
4879 /* PyUnicode_AS_UNICODE OK without thread
4880 lock as it is a simple dereference. */
4881 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4882 Py_END_ALLOW_THREADS
4883 if (fd < 0)
4884 return posix_error();
4885 return PyLong_FromLong((long)fd);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004886 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00004887 /* Drop the argument parsing error as narrow strings
4888 are also valid. */
4889 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004890#endif
4891
Martin v. Löwis011e8422009-05-05 04:43:17 +00004892 if (!PyArg_ParseTuple(args, "O&i|i",
4893 PyUnicode_FSConverter, &ofile,
Mark Hammondef8b6542001-05-13 08:04:26 +00004894 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004895 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004896 file = bytes2str(ofile, 1);
Barry Warsaw53699e91996-12-10 23:23:01 +00004897 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004898 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004899 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004900 if (fd < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004901 return posix_error_with_allocated_filename(ofile);
4902 release_bytes(ofile);
Christian Heimes217cfd12007-12-02 14:31:20 +00004903 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004904}
4905
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004906
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004907PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004908"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004909Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004910
Barry Warsaw53699e91996-12-10 23:23:01 +00004911static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004912posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004913{
4914 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004915 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004916 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00004917 if (!_PyVerify_fd(fd))
4918 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004919 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004920 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004921 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004922 if (res < 0)
4923 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004924 Py_INCREF(Py_None);
4925 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004926}
4927
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004928
Christian Heimesfdab48e2008-01-20 09:06:41 +00004929PyDoc_STRVAR(posix_closerange__doc__,
4930"closerange(fd_low, fd_high)\n\n\
4931Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
4932
4933static PyObject *
4934posix_closerange(PyObject *self, PyObject *args)
4935{
4936 int fd_from, fd_to, i;
4937 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
4938 return NULL;
4939 Py_BEGIN_ALLOW_THREADS
4940 for (i = fd_from; i < fd_to; i++)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00004941 if (_PyVerify_fd(i))
4942 close(i);
Christian Heimesfdab48e2008-01-20 09:06:41 +00004943 Py_END_ALLOW_THREADS
4944 Py_RETURN_NONE;
4945}
4946
4947
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004948PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004949"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004950Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004951
Barry Warsaw53699e91996-12-10 23:23:01 +00004952static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004953posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004954{
4955 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004956 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004957 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00004958 if (!_PyVerify_fd(fd))
4959 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004960 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004961 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004962 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004963 if (fd < 0)
4964 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00004965 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004966}
4967
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004968
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004969PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00004970"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004971Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004972
Barry Warsaw53699e91996-12-10 23:23:01 +00004973static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004974posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004975{
4976 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004977 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004978 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00004979 if (!_PyVerify_fd_dup2(fd, fd2))
4980 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004981 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004982 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004983 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004984 if (res < 0)
4985 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004986 Py_INCREF(Py_None);
4987 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004988}
4989
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004990
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004991PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004992"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004993Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004994
Barry Warsaw53699e91996-12-10 23:23:01 +00004995static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004996posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004997{
4998 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004999#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005000 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005001#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005002 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005003#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005004 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005005 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005006 return NULL;
5007#ifdef SEEK_SET
5008 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5009 switch (how) {
5010 case 0: how = SEEK_SET; break;
5011 case 1: how = SEEK_CUR; break;
5012 case 2: how = SEEK_END; break;
5013 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005014#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005015
5016#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +00005017 pos = PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005018#else
5019 pos = PyLong_Check(posobj) ?
Christian Heimes217cfd12007-12-02 14:31:20 +00005020 PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005021#endif
5022 if (PyErr_Occurred())
5023 return NULL;
5024
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00005025 if (!_PyVerify_fd(fd))
5026 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005027 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005028#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005029 res = _lseeki64(fd, pos, how);
5030#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005031 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005032#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005033 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005034 if (res < 0)
5035 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005036
5037#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +00005038 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005039#else
5040 return PyLong_FromLongLong(res);
5041#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005042}
5043
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005044
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005045PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005046"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005047Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005048
Barry Warsaw53699e91996-12-10 23:23:01 +00005049static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005050posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005051{
Guido van Rossum572dbf82007-04-27 23:53:51 +00005052 int fd, size;
5053 Py_ssize_t n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005054 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005055 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005056 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00005057 if (size < 0) {
5058 errno = EINVAL;
5059 return posix_error();
5060 }
Christian Heimes72b710a2008-05-26 13:28:38 +00005061 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005062 if (buffer == NULL)
5063 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00005064 if (!_PyVerify_fd(fd))
5065 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005066 Py_BEGIN_ALLOW_THREADS
Christian Heimes72b710a2008-05-26 13:28:38 +00005067 n = read(fd, PyBytes_AS_STRING(buffer), size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005068 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005069 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005070 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005071 return posix_error();
5072 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005073 if (n != size)
Christian Heimes72b710a2008-05-26 13:28:38 +00005074 _PyBytes_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005075 return buffer;
5076}
5077
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005078
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005079PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005080"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005081Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005082
Barry Warsaw53699e91996-12-10 23:23:01 +00005083static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005084posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005085{
Martin v. Löwis423be952008-08-13 15:53:07 +00005086 Py_buffer pbuf;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005087 int fd;
5088 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005089
Antoine Pitrou9cadb1b2008-09-15 23:02:56 +00005090 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
Guido van Rossum687dd131993-05-17 08:34:16 +00005091 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00005092 if (!_PyVerify_fd(fd))
5093 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005094 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis423be952008-08-13 15:53:07 +00005095 size = write(fd, pbuf.buf, (size_t)pbuf.len);
Barry Warsaw53699e91996-12-10 23:23:01 +00005096 Py_END_ALLOW_THREADS
Martin v. Löwis423be952008-08-13 15:53:07 +00005097 PyBuffer_Release(&pbuf);
Guido van Rossum687dd131993-05-17 08:34:16 +00005098 if (size < 0)
5099 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00005100 return PyLong_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005101}
5102
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005103
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005104PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005105"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005106Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005107
Barry Warsaw53699e91996-12-10 23:23:01 +00005108static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005109posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005110{
5111 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005112 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005113 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005114 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005115 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005116#ifdef __VMS
5117 /* on OpenVMS we must ensure that all bytes are written to the file */
5118 fsync(fd);
5119#endif
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00005120 if (!_PyVerify_fd(fd))
5121 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005122 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005123 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005124 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00005125 if (res != 0) {
5126#ifdef MS_WINDOWS
5127 return win32_error("fstat", NULL);
5128#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005129 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005130#endif
5131 }
Tim Peters5aa91602002-01-30 05:46:57 +00005132
Martin v. Löwis14694662006-02-03 12:54:16 +00005133 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005134}
5135
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005136PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005137"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005138Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005139connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005140
5141static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005142posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005143{
5144 int fd;
5145 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5146 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00005147 if (!_PyVerify_fd(fd))
5148 return PyBool_FromLong(0);
Fred Drake106c1a02002-04-23 15:58:02 +00005149 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005150}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005151
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005152#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005153PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005154"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005155Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005156
Barry Warsaw53699e91996-12-10 23:23:01 +00005157static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005158posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005159{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005160#if defined(PYOS_OS2)
5161 HFILE read, write;
5162 APIRET rc;
5163
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005164 Py_BEGIN_ALLOW_THREADS
5165 rc = DosCreatePipe( &read, &write, 4096);
5166 Py_END_ALLOW_THREADS
5167 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005168 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005169
5170 return Py_BuildValue("(ii)", read, write);
5171#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005172#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005173 int fds[2];
5174 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005175 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005176 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005177 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005178 if (res != 0)
5179 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005180 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005181#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005182 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005183 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005184 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005185 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005186 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005187 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005188 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005189 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005190 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5191 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005192 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005193#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005194#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005195}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005196#endif /* HAVE_PIPE */
5197
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005198
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005199#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005200PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005201"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005202Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005203
Barry Warsaw53699e91996-12-10 23:23:01 +00005204static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005205posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005206{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005207 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005208 int mode = 0666;
5209 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005210 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005211 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005212 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005213 res = mkfifo(filename, mode);
5214 Py_END_ALLOW_THREADS
5215 if (res < 0)
5216 return posix_error();
5217 Py_INCREF(Py_None);
5218 return Py_None;
5219}
5220#endif
5221
5222
Neal Norwitz11690112002-07-30 01:08:28 +00005223#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005224PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005225"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005226Create a filesystem node (file, device special file or named pipe)\n\
5227named filename. mode specifies both the permissions to use and the\n\
5228type of node to be created, being combined (bitwise OR) with one of\n\
5229S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005230device defines the newly created device special file (probably using\n\
5231os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005232
5233
5234static PyObject *
5235posix_mknod(PyObject *self, PyObject *args)
5236{
5237 char *filename;
5238 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005239 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005240 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005241 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005242 return NULL;
5243 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005244 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005245 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005246 if (res < 0)
5247 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005248 Py_INCREF(Py_None);
5249 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005250}
5251#endif
5252
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005253#ifdef HAVE_DEVICE_MACROS
5254PyDoc_STRVAR(posix_major__doc__,
5255"major(device) -> major number\n\
5256Extracts a device major number from a raw device number.");
5257
5258static PyObject *
5259posix_major(PyObject *self, PyObject *args)
5260{
5261 int device;
5262 if (!PyArg_ParseTuple(args, "i:major", &device))
5263 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +00005264 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005265}
5266
5267PyDoc_STRVAR(posix_minor__doc__,
5268"minor(device) -> minor number\n\
5269Extracts a device minor number from a raw device number.");
5270
5271static PyObject *
5272posix_minor(PyObject *self, PyObject *args)
5273{
5274 int device;
5275 if (!PyArg_ParseTuple(args, "i:minor", &device))
5276 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +00005277 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005278}
5279
5280PyDoc_STRVAR(posix_makedev__doc__,
5281"makedev(major, minor) -> device number\n\
5282Composes a raw device number from the major and minor device numbers.");
5283
5284static PyObject *
5285posix_makedev(PyObject *self, PyObject *args)
5286{
5287 int major, minor;
5288 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5289 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +00005290 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005291}
5292#endif /* device macros */
5293
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005294
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005295#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005296PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005297"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005298Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005299
Barry Warsaw53699e91996-12-10 23:23:01 +00005300static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005301posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005302{
5303 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005304 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005305 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005306 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005307
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005308 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005309 return NULL;
5310
5311#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +00005312 length = PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005313#else
5314 length = PyLong_Check(lenobj) ?
Christian Heimes217cfd12007-12-02 14:31:20 +00005315 PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005316#endif
5317 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005318 return NULL;
5319
Barry Warsaw53699e91996-12-10 23:23:01 +00005320 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005321 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005322 Py_END_ALLOW_THREADS
Benjamin Peterson9053d752009-01-19 17:53:36 +00005323 if (res < 0)
5324 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005325 Py_INCREF(Py_None);
5326 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005327}
5328#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005329
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005330#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005331PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005332"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005333Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005334
Fred Drake762e2061999-08-26 17:23:54 +00005335/* Save putenv() parameters as values here, so we can collect them when they
5336 * get re-set with another call for the same key. */
5337static PyObject *posix_putenv_garbage;
5338
Tim Peters5aa91602002-01-30 05:46:57 +00005339static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005340posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005341{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005342#ifdef MS_WINDOWS
5343 wchar_t *s1, *s2;
5344 wchar_t *newenv;
5345#else
Martin v. Löwis011e8422009-05-05 04:43:17 +00005346 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005347 char *s1, *s2;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005348 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005349#endif
Fred Drake762e2061999-08-26 17:23:54 +00005350 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005351 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005352
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005353#ifdef MS_WINDOWS
Martin v. Löwis011e8422009-05-05 04:43:17 +00005354 if (!PyArg_ParseTuple(args,
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005355 "uu:putenv",
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005356 &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005357 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005358#else
5359 if (!PyArg_ParseTuple(args,
5360 "O&O&:putenv",
5361 PyUnicode_FSConverter, &os1,
5362 PyUnicode_FSConverter, &os2))
5363 return NULL;
5364 s1 = bytes2str(os1, 1);
5365 s2 = bytes2str(os2, 1);
5366#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005367
5368#if defined(PYOS_OS2)
5369 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5370 APIRET rc;
5371
Guido van Rossumd48f2521997-12-05 22:19:34 +00005372 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5373 if (rc != NO_ERROR)
5374 return os2_error(rc);
5375
5376 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5377 APIRET rc;
5378
Guido van Rossumd48f2521997-12-05 22:19:34 +00005379 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5380 if (rc != NO_ERROR)
5381 return os2_error(rc);
5382 } else {
5383#endif
Fred Drake762e2061999-08-26 17:23:54 +00005384 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005385 /* len includes space for a trailing \0; the size arg to
Christian Heimes72b710a2008-05-26 13:28:38 +00005386 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005387#ifdef MS_WINDOWS
5388 len = wcslen(s1) + wcslen(s2) + 2;
5389 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
5390#else
5391 len = strlen(s1) + strlen(s2) + 2;
Christian Heimes72b710a2008-05-26 13:28:38 +00005392 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005393#endif
Fred Drake762e2061999-08-26 17:23:54 +00005394 if (newstr == NULL)
5395 return PyErr_NoMemory();
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005396#ifdef MS_WINDOWS
5397 newenv = PyUnicode_AsUnicode(newstr);
5398 _snwprintf(newenv, len, L"%s=%s", s1, s2);
5399 if (_wputenv(newenv)) {
5400 Py_DECREF(newstr);
5401 posix_error();
5402 return NULL;
5403 }
5404#else
Christian Heimes72b710a2008-05-26 13:28:38 +00005405 newenv = PyBytes_AS_STRING(newstr);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005406 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
5407 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005408 Py_DECREF(newstr);
Martin v. Löwis011e8422009-05-05 04:43:17 +00005409 release_bytes(os1);
5410 release_bytes(os2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005411 posix_error();
5412 return NULL;
5413 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005414#endif
Fred Drake762e2061999-08-26 17:23:54 +00005415 /* Install the first arg and newstr in posix_putenv_garbage;
5416 * this will cause previous value to be collected. This has to
5417 * happen after the real putenv() call because the old value
5418 * was still accessible until then. */
5419 if (PyDict_SetItem(posix_putenv_garbage,
5420 PyTuple_GET_ITEM(args, 0), newstr)) {
5421 /* really not much we can do; just leak */
5422 PyErr_Clear();
5423 }
5424 else {
5425 Py_DECREF(newstr);
5426 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005427
5428#if defined(PYOS_OS2)
5429 }
5430#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00005431#ifndef MS_WINDOWS
5432 release_bytes(os1);
5433 release_bytes(os2);
5434#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005435 Py_INCREF(Py_None);
5436 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005437}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005438#endif /* putenv */
5439
Guido van Rossumc524d952001-10-19 01:31:59 +00005440#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005441PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005442"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005443Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005444
5445static PyObject *
5446posix_unsetenv(PyObject *self, PyObject *args)
5447{
5448 char *s1;
5449
5450 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5451 return NULL;
5452
5453 unsetenv(s1);
5454
5455 /* Remove the key from posix_putenv_garbage;
5456 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005457 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005458 * old value was still accessible until then.
5459 */
5460 if (PyDict_DelItem(posix_putenv_garbage,
5461 PyTuple_GET_ITEM(args, 0))) {
5462 /* really not much we can do; just leak */
5463 PyErr_Clear();
5464 }
5465
5466 Py_INCREF(Py_None);
5467 return Py_None;
5468}
5469#endif /* unsetenv */
5470
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005471PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005472"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005473Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005474
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005475static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005476posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005477{
5478 int code;
5479 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005480 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005481 return NULL;
5482 message = strerror(code);
5483 if (message == NULL) {
5484 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005485 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005486 return NULL;
5487 }
Neal Norwitz93c56822007-08-26 07:10:06 +00005488 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00005489}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005490
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005491
Guido van Rossumc9641791998-08-04 15:26:23 +00005492#ifdef HAVE_SYS_WAIT_H
5493
Fred Drake106c1a02002-04-23 15:58:02 +00005494#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005495PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005496"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005497Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005498
5499static PyObject *
5500posix_WCOREDUMP(PyObject *self, PyObject *args)
5501{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005502 WAIT_TYPE status;
5503 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005504
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005505 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00005506 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005507
5508 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005509}
5510#endif /* WCOREDUMP */
5511
5512#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005513PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005514"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005515Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005516job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005517
5518static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005519posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005520{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005521 WAIT_TYPE status;
5522 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005523
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005524 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00005525 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005526
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005527 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005528}
5529#endif /* WIFCONTINUED */
5530
Guido van Rossumc9641791998-08-04 15:26:23 +00005531#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005532PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005533"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005534Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005535
5536static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005537posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005538{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005539 WAIT_TYPE status;
5540 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005541
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005542 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005543 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005544
Fred Drake106c1a02002-04-23 15:58:02 +00005545 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005546}
5547#endif /* WIFSTOPPED */
5548
5549#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005550PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005551"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005552Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005553
5554static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005555posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005556{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005557 WAIT_TYPE status;
5558 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005559
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005560 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005561 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005562
Fred Drake106c1a02002-04-23 15:58:02 +00005563 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005564}
5565#endif /* WIFSIGNALED */
5566
5567#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005568PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005569"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005570Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005571system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005572
5573static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005574posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005575{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005576 WAIT_TYPE status;
5577 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005578
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005579 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005580 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005581
Fred Drake106c1a02002-04-23 15:58:02 +00005582 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005583}
5584#endif /* WIFEXITED */
5585
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005586#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005587PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005588"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005589Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005590
5591static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005592posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005593{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005594 WAIT_TYPE status;
5595 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005596
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005597 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005598 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005599
Guido van Rossumc9641791998-08-04 15:26:23 +00005600 return Py_BuildValue("i", WEXITSTATUS(status));
5601}
5602#endif /* WEXITSTATUS */
5603
5604#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005605PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005606"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005607Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005608value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005609
5610static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005611posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005612{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005613 WAIT_TYPE status;
5614 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005615
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005616 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005617 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005618
Guido van Rossumc9641791998-08-04 15:26:23 +00005619 return Py_BuildValue("i", WTERMSIG(status));
5620}
5621#endif /* WTERMSIG */
5622
5623#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005624PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005625"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005626Return the signal that stopped the process that provided\n\
5627the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005628
5629static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005630posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005631{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005632 WAIT_TYPE status;
5633 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005634
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005635 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005636 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005637
Guido van Rossumc9641791998-08-04 15:26:23 +00005638 return Py_BuildValue("i", WSTOPSIG(status));
5639}
5640#endif /* WSTOPSIG */
5641
5642#endif /* HAVE_SYS_WAIT_H */
5643
5644
Thomas Wouters477c8d52006-05-27 19:21:47 +00005645#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005646#ifdef _SCO_DS
5647/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5648 needed definitions in sys/statvfs.h */
5649#define _SVID3
5650#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005651#include <sys/statvfs.h>
5652
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005653static PyObject*
5654_pystatvfs_fromstructstatvfs(struct statvfs st) {
5655 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5656 if (v == NULL)
5657 return NULL;
5658
5659#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +00005660 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
5661 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
5662 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
5663 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
5664 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
5665 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
5666 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
5667 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
5668 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
5669 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005670#else
Christian Heimes217cfd12007-12-02 14:31:20 +00005671 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
5672 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005673 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005674 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005675 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005676 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005677 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005678 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005679 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005680 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005681 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005682 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005683 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005684 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Christian Heimes217cfd12007-12-02 14:31:20 +00005685 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
5686 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005687#endif
5688
5689 return v;
5690}
5691
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005692PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005693"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005694Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005695
5696static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005697posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005698{
5699 int fd, res;
5700 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005701
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005702 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005703 return NULL;
5704 Py_BEGIN_ALLOW_THREADS
5705 res = fstatvfs(fd, &st);
5706 Py_END_ALLOW_THREADS
5707 if (res != 0)
5708 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005709
5710 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005711}
Thomas Wouters477c8d52006-05-27 19:21:47 +00005712#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005713
5714
Thomas Wouters477c8d52006-05-27 19:21:47 +00005715#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005716#include <sys/statvfs.h>
5717
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005718PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005719"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005720Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005721
5722static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005723posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005724{
5725 char *path;
5726 int res;
5727 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005728 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005729 return NULL;
5730 Py_BEGIN_ALLOW_THREADS
5731 res = statvfs(path, &st);
5732 Py_END_ALLOW_THREADS
5733 if (res != 0)
5734 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005735
5736 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005737}
5738#endif /* HAVE_STATVFS */
5739
Fred Drakec9680921999-12-13 16:37:25 +00005740/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5741 * It maps strings representing configuration variable names to
5742 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005743 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005744 * rarely-used constants. There are three separate tables that use
5745 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005746 *
5747 * This code is always included, even if none of the interfaces that
5748 * need it are included. The #if hackery needed to avoid it would be
5749 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005750 */
5751struct constdef {
5752 char *name;
5753 long value;
5754};
5755
Fred Drake12c6e2d1999-12-14 21:25:03 +00005756static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005757conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005758 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005759{
Christian Heimes217cfd12007-12-02 14:31:20 +00005760 if (PyLong_Check(arg)) {
5761 *valuep = PyLong_AS_LONG(arg);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005762 return 1;
5763 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00005764 else {
Fred Drake12c6e2d1999-12-14 21:25:03 +00005765 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005766 size_t lo = 0;
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005767 size_t mid;
Fred Drake699f3522000-06-29 21:12:41 +00005768 size_t hi = tablesize;
5769 int cmp;
Guido van Rossumbce56a62007-05-10 18:04:33 +00005770 const char *confname;
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005771 if (!PyUnicode_Check(arg)) {
Guido van Rossumbce56a62007-05-10 18:04:33 +00005772 PyErr_SetString(PyExc_TypeError,
5773 "configuration names must be strings or integers");
5774 return 0;
5775 }
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +00005776 confname = _PyUnicode_AsString(arg);
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005777 if (confname == NULL)
5778 return 0;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005779 while (lo < hi) {
5780 mid = (lo + hi) / 2;
5781 cmp = strcmp(confname, table[mid].name);
5782 if (cmp < 0)
5783 hi = mid;
5784 else if (cmp > 0)
5785 lo = mid + 1;
5786 else {
5787 *valuep = table[mid].value;
5788 return 1;
5789 }
5790 }
5791 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
Guido van Rossumbce56a62007-05-10 18:04:33 +00005792 return 0;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005793 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00005794}
5795
5796
5797#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5798static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005799#ifdef _PC_ABI_AIO_XFER_MAX
5800 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5801#endif
5802#ifdef _PC_ABI_ASYNC_IO
5803 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5804#endif
Fred Drakec9680921999-12-13 16:37:25 +00005805#ifdef _PC_ASYNC_IO
5806 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5807#endif
5808#ifdef _PC_CHOWN_RESTRICTED
5809 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5810#endif
5811#ifdef _PC_FILESIZEBITS
5812 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5813#endif
5814#ifdef _PC_LAST
5815 {"PC_LAST", _PC_LAST},
5816#endif
5817#ifdef _PC_LINK_MAX
5818 {"PC_LINK_MAX", _PC_LINK_MAX},
5819#endif
5820#ifdef _PC_MAX_CANON
5821 {"PC_MAX_CANON", _PC_MAX_CANON},
5822#endif
5823#ifdef _PC_MAX_INPUT
5824 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5825#endif
5826#ifdef _PC_NAME_MAX
5827 {"PC_NAME_MAX", _PC_NAME_MAX},
5828#endif
5829#ifdef _PC_NO_TRUNC
5830 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5831#endif
5832#ifdef _PC_PATH_MAX
5833 {"PC_PATH_MAX", _PC_PATH_MAX},
5834#endif
5835#ifdef _PC_PIPE_BUF
5836 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5837#endif
5838#ifdef _PC_PRIO_IO
5839 {"PC_PRIO_IO", _PC_PRIO_IO},
5840#endif
5841#ifdef _PC_SOCK_MAXBUF
5842 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5843#endif
5844#ifdef _PC_SYNC_IO
5845 {"PC_SYNC_IO", _PC_SYNC_IO},
5846#endif
5847#ifdef _PC_VDISABLE
5848 {"PC_VDISABLE", _PC_VDISABLE},
5849#endif
5850};
5851
Fred Drakec9680921999-12-13 16:37:25 +00005852static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005853conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005854{
5855 return conv_confname(arg, valuep, posix_constants_pathconf,
5856 sizeof(posix_constants_pathconf)
5857 / sizeof(struct constdef));
5858}
5859#endif
5860
5861#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005862PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005863"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005864Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005865If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005866
5867static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005868posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005869{
5870 PyObject *result = NULL;
5871 int name, fd;
5872
Fred Drake12c6e2d1999-12-14 21:25:03 +00005873 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5874 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005875 long limit;
5876
5877 errno = 0;
5878 limit = fpathconf(fd, name);
5879 if (limit == -1 && errno != 0)
5880 posix_error();
5881 else
Christian Heimes217cfd12007-12-02 14:31:20 +00005882 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00005883 }
5884 return result;
5885}
5886#endif
5887
5888
5889#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005890PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005891"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005892Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005893If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005894
5895static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005896posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005897{
5898 PyObject *result = NULL;
5899 int name;
5900 char *path;
5901
5902 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5903 conv_path_confname, &name)) {
5904 long limit;
5905
5906 errno = 0;
5907 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005908 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005909 if (errno == EINVAL)
5910 /* could be a path or name problem */
5911 posix_error();
5912 else
5913 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005914 }
Fred Drakec9680921999-12-13 16:37:25 +00005915 else
Christian Heimes217cfd12007-12-02 14:31:20 +00005916 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00005917 }
5918 return result;
5919}
5920#endif
5921
5922#ifdef HAVE_CONFSTR
5923static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005924#ifdef _CS_ARCHITECTURE
5925 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5926#endif
5927#ifdef _CS_HOSTNAME
5928 {"CS_HOSTNAME", _CS_HOSTNAME},
5929#endif
5930#ifdef _CS_HW_PROVIDER
5931 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5932#endif
5933#ifdef _CS_HW_SERIAL
5934 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5935#endif
5936#ifdef _CS_INITTAB_NAME
5937 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5938#endif
Fred Drakec9680921999-12-13 16:37:25 +00005939#ifdef _CS_LFS64_CFLAGS
5940 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5941#endif
5942#ifdef _CS_LFS64_LDFLAGS
5943 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5944#endif
5945#ifdef _CS_LFS64_LIBS
5946 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5947#endif
5948#ifdef _CS_LFS64_LINTFLAGS
5949 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5950#endif
5951#ifdef _CS_LFS_CFLAGS
5952 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5953#endif
5954#ifdef _CS_LFS_LDFLAGS
5955 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5956#endif
5957#ifdef _CS_LFS_LIBS
5958 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5959#endif
5960#ifdef _CS_LFS_LINTFLAGS
5961 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5962#endif
Fred Draked86ed291999-12-15 15:34:33 +00005963#ifdef _CS_MACHINE
5964 {"CS_MACHINE", _CS_MACHINE},
5965#endif
Fred Drakec9680921999-12-13 16:37:25 +00005966#ifdef _CS_PATH
5967 {"CS_PATH", _CS_PATH},
5968#endif
Fred Draked86ed291999-12-15 15:34:33 +00005969#ifdef _CS_RELEASE
5970 {"CS_RELEASE", _CS_RELEASE},
5971#endif
5972#ifdef _CS_SRPC_DOMAIN
5973 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5974#endif
5975#ifdef _CS_SYSNAME
5976 {"CS_SYSNAME", _CS_SYSNAME},
5977#endif
5978#ifdef _CS_VERSION
5979 {"CS_VERSION", _CS_VERSION},
5980#endif
Fred Drakec9680921999-12-13 16:37:25 +00005981#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5982 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5983#endif
5984#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5985 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5986#endif
5987#ifdef _CS_XBS5_ILP32_OFF32_LIBS
5988 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5989#endif
5990#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5991 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5992#endif
5993#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5994 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5995#endif
5996#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5997 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5998#endif
5999#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6000 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6001#endif
6002#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6003 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6004#endif
6005#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6006 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6007#endif
6008#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6009 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6010#endif
6011#ifdef _CS_XBS5_LP64_OFF64_LIBS
6012 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6013#endif
6014#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6015 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6016#endif
6017#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6018 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6019#endif
6020#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6021 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6022#endif
6023#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6024 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6025#endif
6026#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6027 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6028#endif
Fred Draked86ed291999-12-15 15:34:33 +00006029#ifdef _MIPS_CS_AVAIL_PROCESSORS
6030 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6031#endif
6032#ifdef _MIPS_CS_BASE
6033 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6034#endif
6035#ifdef _MIPS_CS_HOSTID
6036 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6037#endif
6038#ifdef _MIPS_CS_HW_NAME
6039 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6040#endif
6041#ifdef _MIPS_CS_NUM_PROCESSORS
6042 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6043#endif
6044#ifdef _MIPS_CS_OSREL_MAJ
6045 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6046#endif
6047#ifdef _MIPS_CS_OSREL_MIN
6048 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6049#endif
6050#ifdef _MIPS_CS_OSREL_PATCH
6051 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6052#endif
6053#ifdef _MIPS_CS_OS_NAME
6054 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6055#endif
6056#ifdef _MIPS_CS_OS_PROVIDER
6057 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6058#endif
6059#ifdef _MIPS_CS_PROCESSORS
6060 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6061#endif
6062#ifdef _MIPS_CS_SERIAL
6063 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6064#endif
6065#ifdef _MIPS_CS_VENDOR
6066 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6067#endif
Fred Drakec9680921999-12-13 16:37:25 +00006068};
6069
6070static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006071conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006072{
6073 return conv_confname(arg, valuep, posix_constants_confstr,
6074 sizeof(posix_constants_confstr)
6075 / sizeof(struct constdef));
6076}
6077
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006078PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006079"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006080Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006081
6082static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006083posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006084{
6085 PyObject *result = NULL;
6086 int name;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006087 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00006088
6089 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006090 int len;
Fred Drakec9680921999-12-13 16:37:25 +00006091
Fred Drakec9680921999-12-13 16:37:25 +00006092 errno = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006093 len = confstr(name, buffer, sizeof(buffer));
6094 if (len == 0) {
6095 if (errno) {
6096 posix_error();
6097 }
6098 else {
6099 result = Py_None;
6100 Py_INCREF(Py_None);
6101 }
Fred Drakec9680921999-12-13 16:37:25 +00006102 }
6103 else {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006104 if ((unsigned int)len >= sizeof(buffer)) {
Neal Norwitz93c56822007-08-26 07:10:06 +00006105 result = PyUnicode_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006106 if (result != NULL)
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +00006107 confstr(name, _PyUnicode_AsString(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00006108 }
6109 else
Neal Norwitz93c56822007-08-26 07:10:06 +00006110 result = PyUnicode_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006111 }
6112 }
6113 return result;
6114}
6115#endif
6116
6117
6118#ifdef HAVE_SYSCONF
6119static struct constdef posix_constants_sysconf[] = {
6120#ifdef _SC_2_CHAR_TERM
6121 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6122#endif
6123#ifdef _SC_2_C_BIND
6124 {"SC_2_C_BIND", _SC_2_C_BIND},
6125#endif
6126#ifdef _SC_2_C_DEV
6127 {"SC_2_C_DEV", _SC_2_C_DEV},
6128#endif
6129#ifdef _SC_2_C_VERSION
6130 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6131#endif
6132#ifdef _SC_2_FORT_DEV
6133 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6134#endif
6135#ifdef _SC_2_FORT_RUN
6136 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6137#endif
6138#ifdef _SC_2_LOCALEDEF
6139 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6140#endif
6141#ifdef _SC_2_SW_DEV
6142 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6143#endif
6144#ifdef _SC_2_UPE
6145 {"SC_2_UPE", _SC_2_UPE},
6146#endif
6147#ifdef _SC_2_VERSION
6148 {"SC_2_VERSION", _SC_2_VERSION},
6149#endif
Fred Draked86ed291999-12-15 15:34:33 +00006150#ifdef _SC_ABI_ASYNCHRONOUS_IO
6151 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6152#endif
6153#ifdef _SC_ACL
6154 {"SC_ACL", _SC_ACL},
6155#endif
Fred Drakec9680921999-12-13 16:37:25 +00006156#ifdef _SC_AIO_LISTIO_MAX
6157 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6158#endif
Fred Drakec9680921999-12-13 16:37:25 +00006159#ifdef _SC_AIO_MAX
6160 {"SC_AIO_MAX", _SC_AIO_MAX},
6161#endif
6162#ifdef _SC_AIO_PRIO_DELTA_MAX
6163 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6164#endif
6165#ifdef _SC_ARG_MAX
6166 {"SC_ARG_MAX", _SC_ARG_MAX},
6167#endif
6168#ifdef _SC_ASYNCHRONOUS_IO
6169 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6170#endif
6171#ifdef _SC_ATEXIT_MAX
6172 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6173#endif
Fred Draked86ed291999-12-15 15:34:33 +00006174#ifdef _SC_AUDIT
6175 {"SC_AUDIT", _SC_AUDIT},
6176#endif
Fred Drakec9680921999-12-13 16:37:25 +00006177#ifdef _SC_AVPHYS_PAGES
6178 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6179#endif
6180#ifdef _SC_BC_BASE_MAX
6181 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6182#endif
6183#ifdef _SC_BC_DIM_MAX
6184 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6185#endif
6186#ifdef _SC_BC_SCALE_MAX
6187 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6188#endif
6189#ifdef _SC_BC_STRING_MAX
6190 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6191#endif
Fred Draked86ed291999-12-15 15:34:33 +00006192#ifdef _SC_CAP
6193 {"SC_CAP", _SC_CAP},
6194#endif
Fred Drakec9680921999-12-13 16:37:25 +00006195#ifdef _SC_CHARCLASS_NAME_MAX
6196 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6197#endif
6198#ifdef _SC_CHAR_BIT
6199 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6200#endif
6201#ifdef _SC_CHAR_MAX
6202 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6203#endif
6204#ifdef _SC_CHAR_MIN
6205 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6206#endif
6207#ifdef _SC_CHILD_MAX
6208 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6209#endif
6210#ifdef _SC_CLK_TCK
6211 {"SC_CLK_TCK", _SC_CLK_TCK},
6212#endif
6213#ifdef _SC_COHER_BLKSZ
6214 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6215#endif
6216#ifdef _SC_COLL_WEIGHTS_MAX
6217 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6218#endif
6219#ifdef _SC_DCACHE_ASSOC
6220 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6221#endif
6222#ifdef _SC_DCACHE_BLKSZ
6223 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6224#endif
6225#ifdef _SC_DCACHE_LINESZ
6226 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6227#endif
6228#ifdef _SC_DCACHE_SZ
6229 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6230#endif
6231#ifdef _SC_DCACHE_TBLKSZ
6232 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6233#endif
6234#ifdef _SC_DELAYTIMER_MAX
6235 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6236#endif
6237#ifdef _SC_EQUIV_CLASS_MAX
6238 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6239#endif
6240#ifdef _SC_EXPR_NEST_MAX
6241 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6242#endif
6243#ifdef _SC_FSYNC
6244 {"SC_FSYNC", _SC_FSYNC},
6245#endif
6246#ifdef _SC_GETGR_R_SIZE_MAX
6247 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6248#endif
6249#ifdef _SC_GETPW_R_SIZE_MAX
6250 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6251#endif
6252#ifdef _SC_ICACHE_ASSOC
6253 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6254#endif
6255#ifdef _SC_ICACHE_BLKSZ
6256 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6257#endif
6258#ifdef _SC_ICACHE_LINESZ
6259 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6260#endif
6261#ifdef _SC_ICACHE_SZ
6262 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6263#endif
Fred Draked86ed291999-12-15 15:34:33 +00006264#ifdef _SC_INF
6265 {"SC_INF", _SC_INF},
6266#endif
Fred Drakec9680921999-12-13 16:37:25 +00006267#ifdef _SC_INT_MAX
6268 {"SC_INT_MAX", _SC_INT_MAX},
6269#endif
6270#ifdef _SC_INT_MIN
6271 {"SC_INT_MIN", _SC_INT_MIN},
6272#endif
6273#ifdef _SC_IOV_MAX
6274 {"SC_IOV_MAX", _SC_IOV_MAX},
6275#endif
Fred Draked86ed291999-12-15 15:34:33 +00006276#ifdef _SC_IP_SECOPTS
6277 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6278#endif
Fred Drakec9680921999-12-13 16:37:25 +00006279#ifdef _SC_JOB_CONTROL
6280 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6281#endif
Fred Draked86ed291999-12-15 15:34:33 +00006282#ifdef _SC_KERN_POINTERS
6283 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6284#endif
6285#ifdef _SC_KERN_SIM
6286 {"SC_KERN_SIM", _SC_KERN_SIM},
6287#endif
Fred Drakec9680921999-12-13 16:37:25 +00006288#ifdef _SC_LINE_MAX
6289 {"SC_LINE_MAX", _SC_LINE_MAX},
6290#endif
6291#ifdef _SC_LOGIN_NAME_MAX
6292 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6293#endif
6294#ifdef _SC_LOGNAME_MAX
6295 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6296#endif
6297#ifdef _SC_LONG_BIT
6298 {"SC_LONG_BIT", _SC_LONG_BIT},
6299#endif
Fred Draked86ed291999-12-15 15:34:33 +00006300#ifdef _SC_MAC
6301 {"SC_MAC", _SC_MAC},
6302#endif
Fred Drakec9680921999-12-13 16:37:25 +00006303#ifdef _SC_MAPPED_FILES
6304 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6305#endif
6306#ifdef _SC_MAXPID
6307 {"SC_MAXPID", _SC_MAXPID},
6308#endif
6309#ifdef _SC_MB_LEN_MAX
6310 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6311#endif
6312#ifdef _SC_MEMLOCK
6313 {"SC_MEMLOCK", _SC_MEMLOCK},
6314#endif
6315#ifdef _SC_MEMLOCK_RANGE
6316 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6317#endif
6318#ifdef _SC_MEMORY_PROTECTION
6319 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6320#endif
6321#ifdef _SC_MESSAGE_PASSING
6322 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6323#endif
Fred Draked86ed291999-12-15 15:34:33 +00006324#ifdef _SC_MMAP_FIXED_ALIGNMENT
6325 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6326#endif
Fred Drakec9680921999-12-13 16:37:25 +00006327#ifdef _SC_MQ_OPEN_MAX
6328 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6329#endif
6330#ifdef _SC_MQ_PRIO_MAX
6331 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6332#endif
Fred Draked86ed291999-12-15 15:34:33 +00006333#ifdef _SC_NACLS_MAX
6334 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6335#endif
Fred Drakec9680921999-12-13 16:37:25 +00006336#ifdef _SC_NGROUPS_MAX
6337 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6338#endif
6339#ifdef _SC_NL_ARGMAX
6340 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6341#endif
6342#ifdef _SC_NL_LANGMAX
6343 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6344#endif
6345#ifdef _SC_NL_MSGMAX
6346 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6347#endif
6348#ifdef _SC_NL_NMAX
6349 {"SC_NL_NMAX", _SC_NL_NMAX},
6350#endif
6351#ifdef _SC_NL_SETMAX
6352 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6353#endif
6354#ifdef _SC_NL_TEXTMAX
6355 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6356#endif
6357#ifdef _SC_NPROCESSORS_CONF
6358 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6359#endif
6360#ifdef _SC_NPROCESSORS_ONLN
6361 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6362#endif
Fred Draked86ed291999-12-15 15:34:33 +00006363#ifdef _SC_NPROC_CONF
6364 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6365#endif
6366#ifdef _SC_NPROC_ONLN
6367 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6368#endif
Fred Drakec9680921999-12-13 16:37:25 +00006369#ifdef _SC_NZERO
6370 {"SC_NZERO", _SC_NZERO},
6371#endif
6372#ifdef _SC_OPEN_MAX
6373 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6374#endif
6375#ifdef _SC_PAGESIZE
6376 {"SC_PAGESIZE", _SC_PAGESIZE},
6377#endif
6378#ifdef _SC_PAGE_SIZE
6379 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6380#endif
6381#ifdef _SC_PASS_MAX
6382 {"SC_PASS_MAX", _SC_PASS_MAX},
6383#endif
6384#ifdef _SC_PHYS_PAGES
6385 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6386#endif
6387#ifdef _SC_PII
6388 {"SC_PII", _SC_PII},
6389#endif
6390#ifdef _SC_PII_INTERNET
6391 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6392#endif
6393#ifdef _SC_PII_INTERNET_DGRAM
6394 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6395#endif
6396#ifdef _SC_PII_INTERNET_STREAM
6397 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6398#endif
6399#ifdef _SC_PII_OSI
6400 {"SC_PII_OSI", _SC_PII_OSI},
6401#endif
6402#ifdef _SC_PII_OSI_CLTS
6403 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6404#endif
6405#ifdef _SC_PII_OSI_COTS
6406 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6407#endif
6408#ifdef _SC_PII_OSI_M
6409 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6410#endif
6411#ifdef _SC_PII_SOCKET
6412 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6413#endif
6414#ifdef _SC_PII_XTI
6415 {"SC_PII_XTI", _SC_PII_XTI},
6416#endif
6417#ifdef _SC_POLL
6418 {"SC_POLL", _SC_POLL},
6419#endif
6420#ifdef _SC_PRIORITIZED_IO
6421 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6422#endif
6423#ifdef _SC_PRIORITY_SCHEDULING
6424 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6425#endif
6426#ifdef _SC_REALTIME_SIGNALS
6427 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6428#endif
6429#ifdef _SC_RE_DUP_MAX
6430 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6431#endif
6432#ifdef _SC_RTSIG_MAX
6433 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6434#endif
6435#ifdef _SC_SAVED_IDS
6436 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6437#endif
6438#ifdef _SC_SCHAR_MAX
6439 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6440#endif
6441#ifdef _SC_SCHAR_MIN
6442 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6443#endif
6444#ifdef _SC_SELECT
6445 {"SC_SELECT", _SC_SELECT},
6446#endif
6447#ifdef _SC_SEMAPHORES
6448 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6449#endif
6450#ifdef _SC_SEM_NSEMS_MAX
6451 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6452#endif
6453#ifdef _SC_SEM_VALUE_MAX
6454 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6455#endif
6456#ifdef _SC_SHARED_MEMORY_OBJECTS
6457 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6458#endif
6459#ifdef _SC_SHRT_MAX
6460 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6461#endif
6462#ifdef _SC_SHRT_MIN
6463 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6464#endif
6465#ifdef _SC_SIGQUEUE_MAX
6466 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6467#endif
6468#ifdef _SC_SIGRT_MAX
6469 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6470#endif
6471#ifdef _SC_SIGRT_MIN
6472 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6473#endif
Fred Draked86ed291999-12-15 15:34:33 +00006474#ifdef _SC_SOFTPOWER
6475 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6476#endif
Fred Drakec9680921999-12-13 16:37:25 +00006477#ifdef _SC_SPLIT_CACHE
6478 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6479#endif
6480#ifdef _SC_SSIZE_MAX
6481 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6482#endif
6483#ifdef _SC_STACK_PROT
6484 {"SC_STACK_PROT", _SC_STACK_PROT},
6485#endif
6486#ifdef _SC_STREAM_MAX
6487 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6488#endif
6489#ifdef _SC_SYNCHRONIZED_IO
6490 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6491#endif
6492#ifdef _SC_THREADS
6493 {"SC_THREADS", _SC_THREADS},
6494#endif
6495#ifdef _SC_THREAD_ATTR_STACKADDR
6496 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6497#endif
6498#ifdef _SC_THREAD_ATTR_STACKSIZE
6499 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6500#endif
6501#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6502 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6503#endif
6504#ifdef _SC_THREAD_KEYS_MAX
6505 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6506#endif
6507#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6508 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6509#endif
6510#ifdef _SC_THREAD_PRIO_INHERIT
6511 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6512#endif
6513#ifdef _SC_THREAD_PRIO_PROTECT
6514 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6515#endif
6516#ifdef _SC_THREAD_PROCESS_SHARED
6517 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6518#endif
6519#ifdef _SC_THREAD_SAFE_FUNCTIONS
6520 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6521#endif
6522#ifdef _SC_THREAD_STACK_MIN
6523 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6524#endif
6525#ifdef _SC_THREAD_THREADS_MAX
6526 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6527#endif
6528#ifdef _SC_TIMERS
6529 {"SC_TIMERS", _SC_TIMERS},
6530#endif
6531#ifdef _SC_TIMER_MAX
6532 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6533#endif
6534#ifdef _SC_TTY_NAME_MAX
6535 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6536#endif
6537#ifdef _SC_TZNAME_MAX
6538 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6539#endif
6540#ifdef _SC_T_IOV_MAX
6541 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6542#endif
6543#ifdef _SC_UCHAR_MAX
6544 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6545#endif
6546#ifdef _SC_UINT_MAX
6547 {"SC_UINT_MAX", _SC_UINT_MAX},
6548#endif
6549#ifdef _SC_UIO_MAXIOV
6550 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6551#endif
6552#ifdef _SC_ULONG_MAX
6553 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6554#endif
6555#ifdef _SC_USHRT_MAX
6556 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6557#endif
6558#ifdef _SC_VERSION
6559 {"SC_VERSION", _SC_VERSION},
6560#endif
6561#ifdef _SC_WORD_BIT
6562 {"SC_WORD_BIT", _SC_WORD_BIT},
6563#endif
6564#ifdef _SC_XBS5_ILP32_OFF32
6565 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6566#endif
6567#ifdef _SC_XBS5_ILP32_OFFBIG
6568 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6569#endif
6570#ifdef _SC_XBS5_LP64_OFF64
6571 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6572#endif
6573#ifdef _SC_XBS5_LPBIG_OFFBIG
6574 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6575#endif
6576#ifdef _SC_XOPEN_CRYPT
6577 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6578#endif
6579#ifdef _SC_XOPEN_ENH_I18N
6580 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6581#endif
6582#ifdef _SC_XOPEN_LEGACY
6583 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6584#endif
6585#ifdef _SC_XOPEN_REALTIME
6586 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6587#endif
6588#ifdef _SC_XOPEN_REALTIME_THREADS
6589 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6590#endif
6591#ifdef _SC_XOPEN_SHM
6592 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6593#endif
6594#ifdef _SC_XOPEN_UNIX
6595 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6596#endif
6597#ifdef _SC_XOPEN_VERSION
6598 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6599#endif
6600#ifdef _SC_XOPEN_XCU_VERSION
6601 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6602#endif
6603#ifdef _SC_XOPEN_XPG2
6604 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6605#endif
6606#ifdef _SC_XOPEN_XPG3
6607 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6608#endif
6609#ifdef _SC_XOPEN_XPG4
6610 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6611#endif
6612};
6613
6614static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006615conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006616{
6617 return conv_confname(arg, valuep, posix_constants_sysconf,
6618 sizeof(posix_constants_sysconf)
6619 / sizeof(struct constdef));
6620}
6621
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006622PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006623"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006624Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006625
6626static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006627posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006628{
6629 PyObject *result = NULL;
6630 int name;
6631
6632 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6633 int value;
6634
6635 errno = 0;
6636 value = sysconf(name);
6637 if (value == -1 && errno != 0)
6638 posix_error();
6639 else
Christian Heimes217cfd12007-12-02 14:31:20 +00006640 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00006641 }
6642 return result;
6643}
6644#endif
6645
6646
Fred Drakebec628d1999-12-15 18:31:10 +00006647/* This code is used to ensure that the tables of configuration value names
6648 * are in sorted order as required by conv_confname(), and also to build the
6649 * the exported dictionaries that are used to publish information about the
6650 * names available on the host platform.
6651 *
6652 * Sorting the table at runtime ensures that the table is properly ordered
6653 * when used, even for platforms we're not able to test on. It also makes
6654 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006655 */
Fred Drakebec628d1999-12-15 18:31:10 +00006656
6657static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006658cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006659{
6660 const struct constdef *c1 =
6661 (const struct constdef *) v1;
6662 const struct constdef *c2 =
6663 (const struct constdef *) v2;
6664
6665 return strcmp(c1->name, c2->name);
6666}
6667
6668static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006669setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006670 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006671{
Fred Drakebec628d1999-12-15 18:31:10 +00006672 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006673 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006674
6675 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6676 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006677 if (d == NULL)
6678 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006679
Barry Warsaw3155db32000-04-13 15:20:40 +00006680 for (i=0; i < tablesize; ++i) {
Christian Heimes217cfd12007-12-02 14:31:20 +00006681 PyObject *o = PyLong_FromLong(table[i].value);
Barry Warsaw3155db32000-04-13 15:20:40 +00006682 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6683 Py_XDECREF(o);
6684 Py_DECREF(d);
6685 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006686 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006687 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006688 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006689 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006690}
6691
Fred Drakebec628d1999-12-15 18:31:10 +00006692/* Return -1 on failure, 0 on success. */
6693static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006694setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006695{
6696#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006697 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006698 sizeof(posix_constants_pathconf)
6699 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006700 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006701 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006702#endif
6703#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006704 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006705 sizeof(posix_constants_confstr)
6706 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006707 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006708 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006709#endif
6710#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006711 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006712 sizeof(posix_constants_sysconf)
6713 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006714 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006715 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006716#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006717 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006718}
Fred Draked86ed291999-12-15 15:34:33 +00006719
6720
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006721PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006722"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006723Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006724in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006725
6726static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006727posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006728{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006729 abort();
6730 /*NOTREACHED*/
6731 Py_FatalError("abort() called from Python code didn't abort!");
6732 return NULL;
6733}
Fred Drakebec628d1999-12-15 18:31:10 +00006734
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006735#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006736PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00006737"startfile(filepath [, operation]) - Start a file with its associated\n\
6738application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006739\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00006740When \"operation\" is not specified or \"open\", this acts like\n\
6741double-clicking the file in Explorer, or giving the file name as an\n\
6742argument to the DOS \"start\" command: the file is opened with whatever\n\
6743application (if any) its extension is associated.\n\
6744When another \"operation\" is given, it specifies what should be done with\n\
6745the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006746\n\
6747startfile returns as soon as the associated application is launched.\n\
6748There is no option to wait for the application to close, and no way\n\
6749to retrieve the application's exit status.\n\
6750\n\
6751The filepath is relative to the current directory. If you want to use\n\
6752an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006753the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006754
6755static PyObject *
6756win32_startfile(PyObject *self, PyObject *args)
6757{
Martin v. Löwis011e8422009-05-05 04:43:17 +00006758 PyObject *ofilepath;
Tim Petersf58a7aa2000-09-22 10:05:54 +00006759 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00006760 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00006761 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00006762
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00006763 PyObject *unipath, *woperation = NULL;
6764 if (!PyArg_ParseTuple(args, "U|s:startfile",
6765 &unipath, &operation)) {
6766 PyErr_Clear();
6767 goto normal;
6768 }
6769
6770 if (operation) {
6771 woperation = PyUnicode_DecodeASCII(operation,
6772 strlen(operation), NULL);
6773 if (!woperation) {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006774 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00006775 operation = NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006776 goto normal;
6777 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006778 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00006779
6780 Py_BEGIN_ALLOW_THREADS
6781 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
6782 PyUnicode_AS_UNICODE(unipath),
6783 NULL, NULL, SW_SHOWNORMAL);
6784 Py_END_ALLOW_THREADS
6785
6786 Py_XDECREF(woperation);
6787 if (rc <= (HINSTANCE)32) {
6788 PyObject *errval = win32_error_unicode("startfile",
6789 PyUnicode_AS_UNICODE(unipath));
6790 return errval;
6791 }
6792 Py_INCREF(Py_None);
6793 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006794
6795normal:
Martin v. Löwis011e8422009-05-05 04:43:17 +00006796 if (!PyArg_ParseTuple(args, "O&|s:startfile",
6797 PyUnicode_FSConverter, &ofilepath,
Georg Brandlf4f44152006-02-18 22:29:33 +00006798 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00006799 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00006800 filepath = bytes2str(ofilepath, 1);
Tim Petersf58a7aa2000-09-22 10:05:54 +00006801 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00006802 rc = ShellExecute((HWND)0, operation, filepath,
6803 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00006804 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00006805 if (rc <= (HINSTANCE)32) {
6806 PyObject *errval = win32_error("startfile", filepath);
Martin v. Löwis011e8422009-05-05 04:43:17 +00006807 release_bytes(ofilepath);
Georg Brandle9f8ec92005-09-25 06:16:40 +00006808 return errval;
6809 }
Martin v. Löwis011e8422009-05-05 04:43:17 +00006810 release_bytes(ofilepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00006811 Py_INCREF(Py_None);
6812 return Py_None;
6813}
6814#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006815
Martin v. Löwis438b5342002-12-27 10:16:42 +00006816#ifdef HAVE_GETLOADAVG
6817PyDoc_STRVAR(posix_getloadavg__doc__,
6818"getloadavg() -> (float, float, float)\n\n\
6819Return the number of processes in the system run queue averaged over\n\
6820the last 1, 5, and 15 minutes or raises OSError if the load average\n\
6821was unobtainable");
6822
6823static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006824posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00006825{
6826 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00006827 if (getloadavg(loadavg, 3)!=3) {
6828 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
6829 return NULL;
6830 } else
6831 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
6832}
6833#endif
6834
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006835#ifdef MS_WINDOWS
6836
6837PyDoc_STRVAR(win32_urandom__doc__,
6838"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00006839Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006840
6841typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
6842 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
6843 DWORD dwFlags );
6844typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
6845 BYTE *pbBuffer );
6846
6847static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00006848/* This handle is never explicitly released. Instead, the operating
6849 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006850static HCRYPTPROV hCryptProv = 0;
6851
Tim Peters4ad82172004-08-30 17:02:04 +00006852static PyObject*
6853win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006854{
Tim Petersd3115382004-08-30 17:36:46 +00006855 int howMany;
6856 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006857
Tim Peters4ad82172004-08-30 17:02:04 +00006858 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00006859 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00006860 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00006861 if (howMany < 0)
6862 return PyErr_Format(PyExc_ValueError,
6863 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006864
Tim Peters4ad82172004-08-30 17:02:04 +00006865 if (hCryptProv == 0) {
6866 HINSTANCE hAdvAPI32 = NULL;
6867 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006868
Tim Peters4ad82172004-08-30 17:02:04 +00006869 /* Obtain handle to the DLL containing CryptoAPI
6870 This should not fail */
6871 hAdvAPI32 = GetModuleHandle("advapi32.dll");
6872 if(hAdvAPI32 == NULL)
6873 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006874
Tim Peters4ad82172004-08-30 17:02:04 +00006875 /* Obtain pointers to the CryptoAPI functions
6876 This will fail on some early versions of Win95 */
6877 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
6878 hAdvAPI32,
6879 "CryptAcquireContextA");
6880 if (pCryptAcquireContext == NULL)
6881 return PyErr_Format(PyExc_NotImplementedError,
6882 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006883
Tim Peters4ad82172004-08-30 17:02:04 +00006884 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
6885 hAdvAPI32, "CryptGenRandom");
Thomas Wouters89f507f2006-12-13 04:49:30 +00006886 if (pCryptGenRandom == NULL)
Tim Peters4ad82172004-08-30 17:02:04 +00006887 return PyErr_Format(PyExc_NotImplementedError,
6888 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006889
Tim Peters4ad82172004-08-30 17:02:04 +00006890 /* Acquire context */
6891 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
6892 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
6893 return win32_error("CryptAcquireContext", NULL);
6894 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006895
Tim Peters4ad82172004-08-30 17:02:04 +00006896 /* Allocate bytes */
Christian Heimes72b710a2008-05-26 13:28:38 +00006897 result = PyBytes_FromStringAndSize(NULL, howMany);
Tim Petersd3115382004-08-30 17:36:46 +00006898 if (result != NULL) {
6899 /* Get random data */
Amaury Forgeot d'Arca05ada32008-07-21 21:13:14 +00006900 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
Tim Petersd3115382004-08-30 17:36:46 +00006901 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
Christian Heimes72b710a2008-05-26 13:28:38 +00006902 PyBytes_AS_STRING(result))) {
Tim Petersd3115382004-08-30 17:36:46 +00006903 Py_DECREF(result);
6904 return win32_error("CryptGenRandom", NULL);
6905 }
Tim Peters4ad82172004-08-30 17:02:04 +00006906 }
Tim Petersd3115382004-08-30 17:36:46 +00006907 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006908}
6909#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00006910
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00006911PyDoc_STRVAR(device_encoding__doc__,
6912"device_encoding(fd) -> str\n\n\
6913Return a string describing the encoding of the device\n\
6914if the output is a terminal; else return None.");
6915
6916static PyObject *
6917device_encoding(PyObject *self, PyObject *args)
6918{
6919 int fd;
6920 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
6921 return NULL;
Kristján Valur Jónsson649170b2009-03-24 14:15:49 +00006922 if (!_PyVerify_fd(fd) || !isatty(fd)) {
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00006923 Py_INCREF(Py_None);
6924 return Py_None;
6925 }
6926#if defined(MS_WINDOWS) || defined(MS_WIN64)
6927 if (fd == 0) {
6928 char buf[100];
6929 sprintf(buf, "cp%d", GetConsoleCP());
6930 return PyUnicode_FromString(buf);
6931 }
6932 if (fd == 1 || fd == 2) {
6933 char buf[100];
6934 sprintf(buf, "cp%d", GetConsoleOutputCP());
6935 return PyUnicode_FromString(buf);
6936 }
6937#elif defined(CODESET)
6938 {
6939 char *codeset = nl_langinfo(CODESET);
Mark Dickinsonda2706b2008-12-11 18:03:03 +00006940 if (codeset != NULL && codeset[0] != 0)
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00006941 return PyUnicode_FromString(codeset);
6942 }
6943#endif
6944 Py_INCREF(Py_None);
6945 return Py_None;
6946}
6947
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006948#ifdef __VMS
6949/* Use openssl random routine */
6950#include <openssl/rand.h>
6951PyDoc_STRVAR(vms_urandom__doc__,
6952"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00006953Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006954
6955static PyObject*
6956vms_urandom(PyObject *self, PyObject *args)
6957{
6958 int howMany;
6959 PyObject* result;
6960
6961 /* Read arguments */
6962 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
6963 return NULL;
6964 if (howMany < 0)
6965 return PyErr_Format(PyExc_ValueError,
6966 "negative argument not allowed");
6967
6968 /* Allocate bytes */
Christian Heimes72b710a2008-05-26 13:28:38 +00006969 result = PyBytes_FromStringAndSize(NULL, howMany);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006970 if (result != NULL) {
6971 /* Get random data */
6972 if (RAND_pseudo_bytes((unsigned char*)
Christian Heimes72b710a2008-05-26 13:28:38 +00006973 PyBytes_AS_STRING(result),
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006974 howMany) < 0) {
6975 Py_DECREF(result);
6976 return PyErr_Format(PyExc_ValueError,
6977 "RAND_pseudo_bytes");
6978 }
6979 }
6980 return result;
6981}
6982#endif
6983
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006984static PyMethodDef posix_methods[] = {
6985 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6986#ifdef HAVE_TTYNAME
6987 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6988#endif
6989 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00006990#ifdef HAVE_CHFLAGS
6991 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
6992#endif /* HAVE_CHFLAGS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006993 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00006994#ifdef HAVE_FCHMOD
6995 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
6996#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006997#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006998 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006999#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +00007000#ifdef HAVE_LCHMOD
7001 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
7002#endif /* HAVE_LCHMOD */
7003#ifdef HAVE_FCHOWN
7004 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
7005#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00007006#ifdef HAVE_LCHFLAGS
7007 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
7008#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007009#ifdef HAVE_LCHOWN
7010 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7011#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007012#ifdef HAVE_CHROOT
7013 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7014#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007015#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007016 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007017#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007018#ifdef HAVE_GETCWD
Guido van Rossumf0af3e32008-10-02 18:55:37 +00007019 {"getcwd", (PyCFunction)posix_getcwd_unicode,
7020 METH_NOARGS, posix_getcwd__doc__},
7021 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
7022 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007023#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007024#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007025 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007026#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007027 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7028 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7029 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007030#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007031 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007032#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007033#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007034 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007035#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007036 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7037 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7038 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007039 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007040#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007041 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007042#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007043#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007044 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007045#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007046 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007047#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007048 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007049#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007050 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7051 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7052 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007053#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007054 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007055#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007056 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007057#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007058 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7059 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007060#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007061#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007062 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7063 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007064#if defined(PYOS_OS2)
7065 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7066 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
7067#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007068#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007069#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00007070 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007071#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007072#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00007073 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007074#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007075#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00007076 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007077#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007078#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00007079 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007080#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007081#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007082 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007083#endif /* HAVE_GETEGID */
7084#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007085 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007086#endif /* HAVE_GETEUID */
7087#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007088 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007089#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007090#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007091 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007092#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007093 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007094#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007095 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007096#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007097#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007098 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007099#endif /* HAVE_GETPPID */
7100#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007101 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007102#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007103#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007104 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007105#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007106#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007107 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007108#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007109#ifdef HAVE_KILLPG
7110 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7111#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007112#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007113 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007114#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +00007115#ifdef MS_WINDOWS
7116 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
7117#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007118#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007119 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007120#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007121#ifdef HAVE_SETEUID
7122 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7123#endif /* HAVE_SETEUID */
7124#ifdef HAVE_SETEGID
7125 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7126#endif /* HAVE_SETEGID */
7127#ifdef HAVE_SETREUID
7128 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7129#endif /* HAVE_SETREUID */
7130#ifdef HAVE_SETREGID
7131 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7132#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007133#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007134 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007135#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007136#ifdef HAVE_SETGROUPS
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00007137 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007138#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007139#ifdef HAVE_GETPGID
7140 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7141#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007142#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007143 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007144#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007145#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007146 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007147#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007148#ifdef HAVE_WAIT3
7149 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
7150#endif /* HAVE_WAIT3 */
7151#ifdef HAVE_WAIT4
7152 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
7153#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00007154#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007155 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007156#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007157#ifdef HAVE_GETSID
7158 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
7159#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007160#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007161 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007162#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007163#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007164 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007165#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007166#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007167 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007168#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007169#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007170 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007171#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007172 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7173 {"close", posix_close, METH_VARARGS, posix_close__doc__},
Christian Heimesfdab48e2008-01-20 09:06:41 +00007174 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007175 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007176 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7177 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7178 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7179 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7180 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7181 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007182 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007183#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007184 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007185#endif
7186#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007187 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007188#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007189#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007190 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7191#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007192#ifdef HAVE_DEVICE_MACROS
7193 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7194 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7195 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7196#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007197#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007198 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007199#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007200#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007201 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007202#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007203#ifdef HAVE_UNSETENV
7204 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7205#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007206 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007207#ifdef HAVE_FCHDIR
7208 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7209#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007210#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007211 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007212#endif
7213#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007214 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007215#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007216#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007217#ifdef WCOREDUMP
7218 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7219#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007220#ifdef WIFCONTINUED
7221 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7222#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007223#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007224 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007225#endif /* WIFSTOPPED */
7226#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007227 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007228#endif /* WIFSIGNALED */
7229#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007230 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007231#endif /* WIFEXITED */
7232#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007233 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007234#endif /* WEXITSTATUS */
7235#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007236 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007237#endif /* WTERMSIG */
7238#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007239 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007240#endif /* WSTOPSIG */
7241#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00007242#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007243 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007244#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00007245#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007246 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007247#endif
Fred Drakec9680921999-12-13 16:37:25 +00007248#ifdef HAVE_CONFSTR
7249 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7250#endif
7251#ifdef HAVE_SYSCONF
7252 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7253#endif
7254#ifdef HAVE_FPATHCONF
7255 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7256#endif
7257#ifdef HAVE_PATHCONF
7258 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7259#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007260 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007261#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007262 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7263#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007264#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007265 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007266#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007267 #ifdef MS_WINDOWS
7268 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
7269 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007270 #ifdef __VMS
7271 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
7272 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007273 {NULL, NULL} /* Sentinel */
7274};
7275
7276
Barry Warsaw4a342091996-12-19 23:50:02 +00007277static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007278ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007279{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007280 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007281}
7282
Guido van Rossumd48f2521997-12-05 22:19:34 +00007283#if defined(PYOS_OS2)
7284/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007285static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007286{
7287 APIRET rc;
7288 ULONG values[QSV_MAX+1];
7289 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007290 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007291
7292 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007293 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007294 Py_END_ALLOW_THREADS
7295
7296 if (rc != NO_ERROR) {
7297 os2_error(rc);
7298 return -1;
7299 }
7300
Fred Drake4d1e64b2002-04-15 19:40:07 +00007301 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7302 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7303 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7304 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7305 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7306 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7307 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007308
7309 switch (values[QSV_VERSION_MINOR]) {
7310 case 0: ver = "2.00"; break;
7311 case 10: ver = "2.10"; break;
7312 case 11: ver = "2.11"; break;
7313 case 30: ver = "3.00"; break;
7314 case 40: ver = "4.00"; break;
7315 case 50: ver = "5.00"; break;
7316 default:
Tim Peters885d4572001-11-28 20:27:42 +00007317 PyOS_snprintf(tmp, sizeof(tmp),
7318 "%d-%d", values[QSV_VERSION_MAJOR],
7319 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007320 ver = &tmp[0];
7321 }
7322
7323 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007324 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007325 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007326
7327 /* Add Indicator of Which Drive was Used to Boot the System */
7328 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7329 tmp[1] = ':';
7330 tmp[2] = '\0';
7331
Fred Drake4d1e64b2002-04-15 19:40:07 +00007332 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007333}
7334#endif
7335
Barry Warsaw4a342091996-12-19 23:50:02 +00007336static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007337all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007338{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007339#ifdef F_OK
7340 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007341#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007342#ifdef R_OK
7343 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007344#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007345#ifdef W_OK
7346 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007347#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007348#ifdef X_OK
7349 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007350#endif
Fred Drakec9680921999-12-13 16:37:25 +00007351#ifdef NGROUPS_MAX
7352 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7353#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007354#ifdef TMP_MAX
7355 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7356#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007357#ifdef WCONTINUED
7358 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7359#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007360#ifdef WNOHANG
7361 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007362#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007363#ifdef WUNTRACED
7364 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7365#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007366#ifdef O_RDONLY
7367 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7368#endif
7369#ifdef O_WRONLY
7370 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7371#endif
7372#ifdef O_RDWR
7373 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7374#endif
7375#ifdef O_NDELAY
7376 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7377#endif
7378#ifdef O_NONBLOCK
7379 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7380#endif
7381#ifdef O_APPEND
7382 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7383#endif
7384#ifdef O_DSYNC
7385 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7386#endif
7387#ifdef O_RSYNC
7388 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7389#endif
7390#ifdef O_SYNC
7391 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7392#endif
7393#ifdef O_NOCTTY
7394 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7395#endif
7396#ifdef O_CREAT
7397 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7398#endif
7399#ifdef O_EXCL
7400 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7401#endif
7402#ifdef O_TRUNC
7403 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7404#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007405#ifdef O_BINARY
7406 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7407#endif
7408#ifdef O_TEXT
7409 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7410#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007411#ifdef O_LARGEFILE
7412 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7413#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00007414#ifdef O_SHLOCK
7415 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
7416#endif
7417#ifdef O_EXLOCK
7418 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
7419#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007420
Tim Peters5aa91602002-01-30 05:46:57 +00007421/* MS Windows */
7422#ifdef O_NOINHERIT
7423 /* Don't inherit in child processes. */
7424 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7425#endif
7426#ifdef _O_SHORT_LIVED
7427 /* Optimize for short life (keep in memory). */
7428 /* MS forgot to define this one with a non-underscore form too. */
7429 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7430#endif
7431#ifdef O_TEMPORARY
7432 /* Automatically delete when last handle is closed. */
7433 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7434#endif
7435#ifdef O_RANDOM
7436 /* Optimize for random access. */
7437 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7438#endif
7439#ifdef O_SEQUENTIAL
7440 /* Optimize for sequential access. */
7441 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7442#endif
7443
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007444/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +00007445#ifdef O_ASYNC
7446 /* Send a SIGIO signal whenever input or output
7447 becomes available on file descriptor */
7448 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
7449#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007450#ifdef O_DIRECT
7451 /* Direct disk access. */
7452 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7453#endif
7454#ifdef O_DIRECTORY
7455 /* Must be a directory. */
7456 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7457#endif
7458#ifdef O_NOFOLLOW
7459 /* Do not follow links. */
7460 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7461#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00007462#ifdef O_NOATIME
7463 /* Do not update the access time. */
7464 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
7465#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007466
Barry Warsaw5676bd12003-01-07 20:57:09 +00007467 /* These come from sysexits.h */
7468#ifdef EX_OK
7469 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007470#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007471#ifdef EX_USAGE
7472 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007473#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007474#ifdef EX_DATAERR
7475 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007476#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007477#ifdef EX_NOINPUT
7478 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007479#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007480#ifdef EX_NOUSER
7481 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007482#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007483#ifdef EX_NOHOST
7484 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007485#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007486#ifdef EX_UNAVAILABLE
7487 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007488#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007489#ifdef EX_SOFTWARE
7490 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007491#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007492#ifdef EX_OSERR
7493 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007494#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007495#ifdef EX_OSFILE
7496 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007497#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007498#ifdef EX_CANTCREAT
7499 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007500#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007501#ifdef EX_IOERR
7502 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007503#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007504#ifdef EX_TEMPFAIL
7505 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007506#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007507#ifdef EX_PROTOCOL
7508 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007509#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007510#ifdef EX_NOPERM
7511 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007512#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007513#ifdef EX_CONFIG
7514 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007515#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007516#ifdef EX_NOTFOUND
7517 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007518#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007519
Guido van Rossum246bc171999-02-01 23:54:31 +00007520#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007521#if defined(PYOS_OS2) && defined(PYCC_GCC)
7522 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7523 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7524 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7525 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7526 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7527 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7528 if (ins(d, "P_PM", (long)P_PM)) return -1;
7529 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7530 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7531 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7532 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7533 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7534 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7535 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7536 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7537 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7538 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7539 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7540 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7541 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7542#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007543 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7544 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7545 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7546 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7547 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007548#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007549#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007550
Guido van Rossumd48f2521997-12-05 22:19:34 +00007551#if defined(PYOS_OS2)
7552 if (insertvalues(d)) return -1;
7553#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007554 return 0;
7555}
7556
7557
Tim Peters5aa91602002-01-30 05:46:57 +00007558#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007559#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007560#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007561
7562#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007563#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007564#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007565
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007566#else
Martin v. Löwis1a214512008-06-11 05:26:20 +00007567#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007568#define MODNAME "posix"
7569#endif
7570
Martin v. Löwis1a214512008-06-11 05:26:20 +00007571static struct PyModuleDef posixmodule = {
7572 PyModuleDef_HEAD_INIT,
7573 MODNAME,
7574 posix__doc__,
7575 -1,
7576 posix_methods,
7577 NULL,
7578 NULL,
7579 NULL,
7580 NULL
7581};
7582
7583
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007584PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007585INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007586{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007587 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007588
Martin v. Löwis1a214512008-06-11 05:26:20 +00007589 m = PyModule_Create(&posixmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00007590 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007591 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007592
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007593 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007594 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007595 Py_XINCREF(v);
7596 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007597 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00007598 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007599
Fred Drake4d1e64b2002-04-15 19:40:07 +00007600 if (all_ins(m))
Martin v. Löwis1a214512008-06-11 05:26:20 +00007601 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +00007602
Fred Drake4d1e64b2002-04-15 19:40:07 +00007603 if (setup_confname_tables(m))
Martin v. Löwis1a214512008-06-11 05:26:20 +00007604 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +00007605
Fred Drake4d1e64b2002-04-15 19:40:07 +00007606 Py_INCREF(PyExc_OSError);
7607 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007608
Guido van Rossumb3d39562000-01-31 18:41:26 +00007609#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007610 if (posix_putenv_garbage == NULL)
7611 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007612#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007613
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007614 if (!initialized) {
7615 stat_result_desc.name = MODNAME ".stat_result";
7616 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7617 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7618 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
7619 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
7620 structseq_new = StatResultType.tp_new;
7621 StatResultType.tp_new = statresult_new;
7622
7623 statvfs_result_desc.name = MODNAME ".statvfs_result";
7624 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00007625#ifdef NEED_TICKS_PER_SECOND
7626# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
7627 ticks_per_second = sysconf(_SC_CLK_TCK);
7628# elif defined(HZ)
7629 ticks_per_second = HZ;
7630# else
7631 ticks_per_second = 60; /* magic fallback value; may be bogus */
7632# endif
7633#endif
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007634 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007635 Py_INCREF((PyObject*) &StatResultType);
7636 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007637 Py_INCREF((PyObject*) &StatVFSResultType);
7638 PyModule_AddObject(m, "statvfs_result",
7639 (PyObject*) &StatVFSResultType);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007640 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007641
7642#ifdef __APPLE__
7643 /*
7644 * Step 2 of weak-linking support on Mac OS X.
7645 *
7646 * The code below removes functions that are not available on the
7647 * currently active platform.
7648 *
7649 * This block allow one to use a python binary that was build on
7650 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
7651 * OSX 10.4.
7652 */
7653#ifdef HAVE_FSTATVFS
7654 if (fstatvfs == NULL) {
7655 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
Martin v. Löwis1a214512008-06-11 05:26:20 +00007656 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007657 }
7658 }
7659#endif /* HAVE_FSTATVFS */
7660
7661#ifdef HAVE_STATVFS
7662 if (statvfs == NULL) {
7663 if (PyObject_DelAttrString(m, "statvfs") == -1) {
Martin v. Löwis1a214512008-06-11 05:26:20 +00007664 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007665 }
7666 }
7667#endif /* HAVE_STATVFS */
7668
7669# ifdef HAVE_LCHOWN
7670 if (lchown == NULL) {
7671 if (PyObject_DelAttrString(m, "lchown") == -1) {
Martin v. Löwis1a214512008-06-11 05:26:20 +00007672 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007673 }
7674 }
7675#endif /* HAVE_LCHOWN */
7676
7677
7678#endif /* __APPLE__ */
Martin v. Löwis1a214512008-06-11 05:26:20 +00007679 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007680
Guido van Rossumb6775db1994-08-01 11:34:53 +00007681}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007682
7683#ifdef __cplusplus
7684}
7685#endif