blob: ad4fff0c78a9115be2135fd8d152fa67e0330b86 [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
Greg Wardb48bc172000-03-01 21:51:56 +0000306/* Don't use the "_r" form if we don't need it (also, won't have a
307 prototype for it, at least on Solaris -- maybe others as well?). */
308#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
309#define USE_CTERMID_R
310#endif
311
Fred Drake699f3522000-06-29 21:12:41 +0000312/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000313#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000314#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwis14694662006-02-03 12:54:16 +0000315# define STAT win32_stat
316# define FSTAT win32_fstat
317# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000318#else
319# define STAT stat
320# define FSTAT fstat
321# define STRUCT_STAT struct stat
322#endif
323
Tim Peters11b23062003-04-23 02:39:17 +0000324#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000325#include <sys/mkdev.h>
326#else
327#if defined(MAJOR_IN_SYSMACROS)
328#include <sys/sysmacros.h>
329#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000330#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
331#include <sys/mkdev.h>
332#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000333#endif
Fred Drake699f3522000-06-29 21:12:41 +0000334
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000335#if defined _MSC_VER && _MSC_VER >= 1400
336/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
337 * valid and throw an assertion if it isn't.
338 * Normally, an invalid fd is likely to be a C program error and therefore
339 * an assertion can be useful, but it does contradict the POSIX standard
340 * which for write(2) states:
341 * "Otherwise, -1 shall be returned and errno set to indicate the error."
342 * "[EBADF] The fildes argument is not a valid file descriptor open for
343 * writing."
344 * Furthermore, python allows the user to enter any old integer
345 * as a fd and should merely raise a python exception on error.
346 * The Microsoft CRT doesn't provide an official way to check for the
347 * validity of a file descriptor, but we can emulate its internal behaviour
348 * by using the exported __pinfo data member and knowledge of the
349 * internal structures involved.
350 * The structures below must be updated for each version of visual studio
351 * according to the file internal.h in the CRT source, until MS comes
352 * up with a less hacky way to do this.
353 * (all of this is to avoid globally modifying the CRT behaviour using
354 * _set_invalid_parameter_handler() and _CrtSetReportMode())
355 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000356/* The actual size of the structure is determined at runtime.
357 * Only the first items must be present.
358 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000359typedef struct {
360 intptr_t osfhnd;
361 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000362} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000363
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000364extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000365#define IOINFO_L2E 5
366#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
367#define IOINFO_ARRAYS 64
368#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
369#define FOPEN 0x01
370#define _NO_CONSOLE_FILENO (intptr_t)-2
371
372/* This function emulates what the windows CRT does to validate file handles */
373int
374_PyVerify_fd(int fd)
375{
376 const int i1 = fd >> IOINFO_L2E;
377 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000378
379 static int sizeof_ioinfo = 0;
380
381 /* Determine the actual size of the ioinfo structure,
382 * as used by the CRT loaded in memory
383 */
384 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
385 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
386 }
387 if (sizeof_ioinfo == 0) {
388 /* This should not happen... */
389 goto fail;
390 }
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000391
392 /* See that it isn't a special CLEAR fileno */
393 if (fd != _NO_CONSOLE_FILENO) {
394 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
395 * we check pointer validity and other info
396 */
397 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
398 /* finally, check that the file is open */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000399 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
400 if (info->osfile & FOPEN) {
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000401 return 1;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000402 }
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000403 }
404 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000405 fail:
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000406 errno = EBADF;
407 return 0;
408}
409
410/* the special case of checking dup2. The target fd must be in a sensible range */
411static int
412_PyVerify_fd_dup2(int fd1, int fd2)
413{
414 if (!_PyVerify_fd(fd1))
415 return 0;
416 if (fd2 == _NO_CONSOLE_FILENO)
417 return 0;
418 if ((unsigned)fd2 < _NHANDLE_)
419 return 1;
420 else
421 return 0;
422}
423#else
424/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
425#define _PyVerify_fd_dup2(A, B) (1)
426#endif
427
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000428/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000429#ifdef WITH_NEXT_FRAMEWORK
430/* On Darwin/MacOSX a shared library or framework has no access to
431** environ directly, we must obtain it with _NSGetEnviron().
432*/
433#include <crt_externs.h>
434static char **environ;
435#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000436extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000437#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000438
Barry Warsaw53699e91996-12-10 23:23:01 +0000439static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000440convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000441{
Barry Warsaw53699e91996-12-10 23:23:01 +0000442 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000443#ifdef MS_WINDOWS
444 wchar_t **e;
445#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000446 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000447#endif
Barry Warsaw53699e91996-12-10 23:23:01 +0000448 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000449 if (d == NULL)
450 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000451#ifdef WITH_NEXT_FRAMEWORK
452 if (environ == NULL)
453 environ = *_NSGetEnviron();
454#endif
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000455#ifdef MS_WINDOWS
456 /* _wenviron must be initialized in this way if the program is started
457 through main() instead of wmain(). */
458 _wgetenv(L"");
459 if (_wenviron == NULL)
460 return d;
461 /* This part ignores errors */
462 for (e = _wenviron; *e != NULL; e++) {
463 PyObject *k;
464 PyObject *v;
465 wchar_t *p = wcschr(*e, L'=');
466 if (p == NULL)
467 continue;
468 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
469 if (k == NULL) {
470 PyErr_Clear();
471 continue;
472 }
473 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
474 if (v == NULL) {
475 PyErr_Clear();
476 Py_DECREF(k);
477 continue;
478 }
479 if (PyDict_GetItem(d, k) == NULL) {
480 if (PyDict_SetItem(d, k, v) != 0)
481 PyErr_Clear();
482 }
483 Py_DECREF(k);
484 Py_DECREF(v);
485 }
486#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000487 if (environ == NULL)
488 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000489 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000490 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000491 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000492 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000493 char *p = strchr(*e, '=');
494 if (p == NULL)
495 continue;
Martin v. Löwis011e8422009-05-05 04:43:17 +0000496 k = PyUnicode_Decode(*e, (int)(p-*e),
Martin v. Löwis43c57782009-05-10 08:15:24 +0000497 Py_FileSystemDefaultEncoding, "surrogateescape");
Guido van Rossum6a619f41999-08-03 19:41:10 +0000498 if (k == NULL) {
499 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000500 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000501 }
Martin v. Löwis011e8422009-05-05 04:43:17 +0000502 v = PyUnicode_Decode(p+1, strlen(p+1),
Martin v. Löwis43c57782009-05-10 08:15:24 +0000503 Py_FileSystemDefaultEncoding, "surrogateescape");
Guido van Rossum6a619f41999-08-03 19:41:10 +0000504 if (v == NULL) {
505 PyErr_Clear();
506 Py_DECREF(k);
507 continue;
508 }
509 if (PyDict_GetItem(d, k) == NULL) {
510 if (PyDict_SetItem(d, k, v) != 0)
511 PyErr_Clear();
512 }
513 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000514 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000515 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000516#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000517#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000518 {
519 APIRET rc;
520 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
521
522 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000523 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Christian Heimes72b710a2008-05-26 13:28:38 +0000524 PyObject *v = PyBytes_FromString(buffer);
Neal Norwitz93c56822007-08-26 07:10:06 +0000525 PyDict_SetItemString(d, "BEGINLIBPATH", v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000526 Py_DECREF(v);
527 }
528 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
529 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
Christian Heimes72b710a2008-05-26 13:28:38 +0000530 PyObject *v = PyBytes_FromString(buffer);
Neal Norwitz93c56822007-08-26 07:10:06 +0000531 PyDict_SetItemString(d, "ENDLIBPATH", v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000532 Py_DECREF(v);
533 }
534 }
535#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000536 return d;
537}
538
Martin v. Löwis011e8422009-05-05 04:43:17 +0000539/* Convert a bytes object to a char*. Optionally lock the buffer if it is a
540 bytes array. */
541
542static char*
543bytes2str(PyObject* o, int lock)
544{
545 if(PyBytes_Check(o))
546 return PyBytes_AsString(o);
547 else if(PyByteArray_Check(o)) {
548 if (lock && PyObject_GetBuffer(o, NULL, 0) < 0)
549 /* On a bytearray, this should not fail. */
550 PyErr_BadInternalCall();
551 return PyByteArray_AsString(o);
552 } else {
553 /* The FS converter should have verified that this
554 is either bytes or bytearray. */
555 Py_FatalError("bad object passed to bytes2str");
556 /* not reached. */
557 return "";
558 }
559}
560
561/* Release the lock, decref the object. */
562static void
563release_bytes(PyObject* o)
564{
565 if (PyByteArray_Check(o))
566 o->ob_type->tp_as_buffer->bf_releasebuffer(NULL, 0);
567 Py_DECREF(o);
568}
569
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000570
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000571/* Set a POSIX-specific error from errno, and return NULL */
572
Barry Warsawd58d7641998-07-23 16:14:40 +0000573static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000574posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000575{
Barry Warsawca74da41999-02-09 19:31:45 +0000576 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000577}
Barry Warsawd58d7641998-07-23 16:14:40 +0000578static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000579posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000580{
Barry Warsawca74da41999-02-09 19:31:45 +0000581 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000582}
583
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000584#ifdef Py_WIN_WIDE_FILENAMES
585static PyObject *
586posix_error_with_unicode_filename(Py_UNICODE* name)
587{
588 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
589}
590#endif /* Py_WIN_WIDE_FILENAMES */
591
592
Mark Hammondef8b6542001-05-13 08:04:26 +0000593static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +0000594posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +0000595{
Martin v. Löwis011e8422009-05-05 04:43:17 +0000596 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError,
597 bytes2str(name, 0));
598 release_bytes(name);
Mark Hammondef8b6542001-05-13 08:04:26 +0000599 return rc;
600}
601
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000602#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000603static PyObject *
604win32_error(char* function, char* filename)
605{
Mark Hammond33a6da92000-08-15 00:46:38 +0000606 /* XXX We should pass the function name along in the future.
Georg Brandl38feaf02008-05-25 07:45:51 +0000607 (winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000608 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000609 Windows error object, which is non-trivial.
610 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000611 errno = GetLastError();
612 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000613 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000614 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000615 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000616}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000617
618#ifdef Py_WIN_WIDE_FILENAMES
619static PyObject *
620win32_error_unicode(char* function, Py_UNICODE* filename)
621{
622 /* XXX - see win32_error for comments on 'function' */
623 errno = GetLastError();
624 if (filename)
625 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
626 else
627 return PyErr_SetFromWindowsErr(errno);
628}
629
Thomas Wouters477c8d52006-05-27 19:21:47 +0000630static int
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000631convert_to_unicode(PyObject **param)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000632{
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000633 if (PyUnicode_CheckExact(*param))
634 Py_INCREF(*param);
635 else if (PyUnicode_Check(*param))
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000636 /* For a Unicode subtype that's not a Unicode object,
637 return a true Unicode object with the same data. */
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000638 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
639 PyUnicode_GET_SIZE(*param));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000640 else
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000641 *param = PyUnicode_FromEncodedObject(*param,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000642 Py_FileSystemDefaultEncoding,
643 "strict");
644 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000645}
646
647#endif /* Py_WIN_WIDE_FILENAMES */
648
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000649#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000650
Guido van Rossumd48f2521997-12-05 22:19:34 +0000651#if defined(PYOS_OS2)
652/**********************************************************************
653 * Helper Function to Trim and Format OS/2 Messages
654 **********************************************************************/
655 static void
656os2_formatmsg(char *msgbuf, int msglen, char *reason)
657{
658 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
659
660 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
661 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
662
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000663 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000664 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
665 }
666
667 /* Add Optional Reason Text */
668 if (reason) {
669 strcat(msgbuf, " : ");
670 strcat(msgbuf, reason);
671 }
672}
673
674/**********************************************************************
675 * Decode an OS/2 Operating System Error Code
676 *
677 * A convenience function to lookup an OS/2 error code and return a
678 * text message we can use to raise a Python exception.
679 *
680 * Notes:
681 * The messages for errors returned from the OS/2 kernel reside in
682 * the file OSO001.MSG in the \OS2 directory hierarchy.
683 *
684 **********************************************************************/
685 static char *
686os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
687{
688 APIRET rc;
689 ULONG msglen;
690
691 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
692 Py_BEGIN_ALLOW_THREADS
693 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
694 errorcode, "oso001.msg", &msglen);
695 Py_END_ALLOW_THREADS
696
697 if (rc == NO_ERROR)
698 os2_formatmsg(msgbuf, msglen, reason);
699 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000700 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000701 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000702
703 return msgbuf;
704}
705
706/* Set an OS/2-specific error and return NULL. OS/2 kernel
707 errors are not in a global variable e.g. 'errno' nor are
708 they congruent with posix error numbers. */
709
710static PyObject * os2_error(int code)
711{
712 char text[1024];
713 PyObject *v;
714
715 os2_strerror(text, sizeof(text), code, "");
716
717 v = Py_BuildValue("(is)", code, text);
718 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000719 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000720 Py_DECREF(v);
721 }
722 return NULL; /* Signal to Python that an Exception is Pending */
723}
724
725#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000726
727/* POSIX generic methods */
728
Barry Warsaw53699e91996-12-10 23:23:01 +0000729static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000730posix_fildes(PyObject *fdobj, int (*func)(int))
731{
732 int fd;
733 int res;
734 fd = PyObject_AsFileDescriptor(fdobj);
735 if (fd < 0)
736 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000737 if (!_PyVerify_fd(fd))
738 return posix_error();
Fred Drake4d1e64b2002-04-15 19:40:07 +0000739 Py_BEGIN_ALLOW_THREADS
740 res = (*func)(fd);
741 Py_END_ALLOW_THREADS
742 if (res < 0)
743 return posix_error();
744 Py_INCREF(Py_None);
745 return Py_None;
746}
Guido van Rossum21142a01999-01-08 21:05:37 +0000747
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000748#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000749static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000750unicode_file_names(void)
751{
752 static int canusewide = -1;
753 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000754 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000755 the Windows NT family. */
756 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
757 }
758 return canusewide;
759}
760#endif
Tim Peters11b23062003-04-23 02:39:17 +0000761
Guido van Rossum21142a01999-01-08 21:05:37 +0000762static 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)) {
793 Py_XDECREF(opath1);
794 Py_XDECREF(opath2);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000795 return NULL;
Antoine Pitroua6bb9842009-05-10 22:27:00 +0000796 }
Martin v. Löwis011e8422009-05-05 04:43:17 +0000797 path1 = bytes2str(opath1, 1);
798 path2 = bytes2str(opath2, 1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000799 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000800 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000801 Py_END_ALLOW_THREADS
Martin v. Löwis011e8422009-05-05 04:43:17 +0000802 release_bytes(opath1);
803 release_bytes(opath2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000804 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000805 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000806 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000807 Py_INCREF(Py_None);
808 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000809}
810
Thomas Wouters477c8d52006-05-27 19:21:47 +0000811#ifdef Py_WIN_WIDE_FILENAMES
812static PyObject*
813win32_1str(PyObject* args, char* func,
814 char* format, BOOL (__stdcall *funcA)(LPCSTR),
815 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
816{
817 PyObject *uni;
818 char *ansi;
819 BOOL result;
820 if (unicode_file_names()) {
821 if (!PyArg_ParseTuple(args, wformat, &uni))
822 PyErr_Clear();
823 else {
824 Py_BEGIN_ALLOW_THREADS
825 result = funcW(PyUnicode_AsUnicode(uni));
826 Py_END_ALLOW_THREADS
827 if (!result)
828 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
829 Py_INCREF(Py_None);
830 return Py_None;
831 }
832 }
833 if (!PyArg_ParseTuple(args, format, &ansi))
834 return NULL;
835 Py_BEGIN_ALLOW_THREADS
836 result = funcA(ansi);
837 Py_END_ALLOW_THREADS
838 if (!result)
839 return win32_error(func, ansi);
840 Py_INCREF(Py_None);
841 return Py_None;
842
843}
844
845/* This is a reimplementation of the C library's chdir function,
846 but one that produces Win32 errors instead of DOS error codes.
847 chdir is essentially a wrapper around SetCurrentDirectory; however,
848 it also needs to set "magic" environment variables indicating
849 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000850static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000851win32_chdir(LPCSTR path)
852{
853 char new_path[MAX_PATH+1];
854 int result;
855 char env[4] = "=x:";
856
857 if(!SetCurrentDirectoryA(path))
858 return FALSE;
859 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
860 if (!result)
861 return FALSE;
862 /* In the ANSI API, there should not be any paths longer
863 than MAX_PATH. */
864 assert(result <= MAX_PATH+1);
865 if (strncmp(new_path, "\\\\", 2) == 0 ||
866 strncmp(new_path, "//", 2) == 0)
867 /* UNC path, nothing to do. */
868 return TRUE;
869 env[1] = new_path[0];
870 return SetEnvironmentVariableA(env, new_path);
871}
872
873/* The Unicode version differs from the ANSI version
874 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000875static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000876win32_wchdir(LPCWSTR path)
877{
878 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
879 int result;
880 wchar_t env[4] = L"=x:";
881
882 if(!SetCurrentDirectoryW(path))
883 return FALSE;
884 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
885 if (!result)
886 return FALSE;
887 if (result > MAX_PATH+1) {
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000888 new_path = malloc(result * sizeof(wchar_t));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000889 if (!new_path) {
890 SetLastError(ERROR_OUTOFMEMORY);
891 return FALSE;
892 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000893 result = GetCurrentDirectoryW(result, new_path);
894 if (!result) {
895 free(new_path);
896 return FALSE;
897 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000898 }
899 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
900 wcsncmp(new_path, L"//", 2) == 0)
901 /* UNC path, nothing to do. */
902 return TRUE;
903 env[1] = new_path[0];
904 result = SetEnvironmentVariableW(env, new_path);
905 if (new_path != _new_path)
906 free(new_path);
907 return result;
908}
909#endif
910
Martin v. Löwis14694662006-02-03 12:54:16 +0000911#ifdef MS_WINDOWS
912/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
913 - time stamps are restricted to second resolution
914 - file modification times suffer from forth-and-back conversions between
915 UTC and local time
916 Therefore, we implement our own stat, based on the Win32 API directly.
917*/
918#define HAVE_STAT_NSEC 1
919
920struct win32_stat{
921 int st_dev;
922 __int64 st_ino;
923 unsigned short st_mode;
924 int st_nlink;
925 int st_uid;
926 int st_gid;
927 int st_rdev;
928 __int64 st_size;
929 int st_atime;
930 int st_atime_nsec;
931 int st_mtime;
932 int st_mtime_nsec;
933 int st_ctime;
934 int st_ctime_nsec;
935};
936
937static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
938
939static void
940FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
941{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000942 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
943 /* Cannot simply cast and dereference in_ptr,
944 since it might not be aligned properly */
945 __int64 in;
946 memcpy(&in, in_ptr, sizeof(in));
Martin v. Löwis14694662006-02-03 12:54:16 +0000947 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
948 /* XXX Win32 supports time stamps past 2038; we currently don't */
949 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
950}
951
Thomas Wouters477c8d52006-05-27 19:21:47 +0000952static void
953time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
954{
955 /* XXX endianness */
956 __int64 out;
957 out = time_in + secs_between_epochs;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000958 out = out * 10000000 + nsec_in / 100;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000959 memcpy(out_ptr, &out, sizeof(out));
960}
961
Martin v. Löwis14694662006-02-03 12:54:16 +0000962/* Below, we *know* that ugo+r is 0444 */
963#if _S_IREAD != 0400
964#error Unsupported C library
965#endif
966static int
967attributes_to_mode(DWORD attr)
968{
969 int m = 0;
970 if (attr & FILE_ATTRIBUTE_DIRECTORY)
971 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
972 else
973 m |= _S_IFREG;
974 if (attr & FILE_ATTRIBUTE_READONLY)
975 m |= 0444;
976 else
977 m |= 0666;
978 return m;
979}
980
981static int
982attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
983{
984 memset(result, 0, sizeof(*result));
985 result->st_mode = attributes_to_mode(info->dwFileAttributes);
986 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
987 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
988 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
989 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
990
991 return 0;
992}
993
Thomas Wouters89f507f2006-12-13 04:49:30 +0000994/* Emulate GetFileAttributesEx[AW] on Windows 95 */
995static int checked = 0;
996static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
997static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
998static void
999check_gfax()
1000{
1001 HINSTANCE hKernel32;
1002 if (checked)
1003 return;
1004 checked = 1;
1005 hKernel32 = GetModuleHandle("KERNEL32");
1006 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
1007 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
1008}
1009
Guido van Rossumd8faa362007-04-27 19:54:29 +00001010static BOOL
1011attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
1012{
1013 HANDLE hFindFile;
1014 WIN32_FIND_DATAA FileData;
1015 hFindFile = FindFirstFileA(pszFile, &FileData);
1016 if (hFindFile == INVALID_HANDLE_VALUE)
1017 return FALSE;
1018 FindClose(hFindFile);
1019 pfad->dwFileAttributes = FileData.dwFileAttributes;
1020 pfad->ftCreationTime = FileData.ftCreationTime;
1021 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
1022 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
1023 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
1024 pfad->nFileSizeLow = FileData.nFileSizeLow;
1025 return TRUE;
1026}
1027
1028static BOOL
1029attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
1030{
1031 HANDLE hFindFile;
1032 WIN32_FIND_DATAW FileData;
1033 hFindFile = FindFirstFileW(pszFile, &FileData);
1034 if (hFindFile == INVALID_HANDLE_VALUE)
1035 return FALSE;
1036 FindClose(hFindFile);
1037 pfad->dwFileAttributes = FileData.dwFileAttributes;
1038 pfad->ftCreationTime = FileData.ftCreationTime;
1039 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
1040 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
1041 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
1042 pfad->nFileSizeLow = FileData.nFileSizeLow;
1043 return TRUE;
1044}
1045
Thomas Wouters89f507f2006-12-13 04:49:30 +00001046static BOOL WINAPI
1047Py_GetFileAttributesExA(LPCSTR pszFile,
1048 GET_FILEEX_INFO_LEVELS level,
1049 LPVOID pv)
1050{
1051 BOOL result;
Thomas Wouters89f507f2006-12-13 04:49:30 +00001052 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
1053 /* First try to use the system's implementation, if that is
1054 available and either succeeds to gives an error other than
1055 that it isn't implemented. */
1056 check_gfax();
1057 if (gfaxa) {
1058 result = gfaxa(pszFile, level, pv);
1059 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
1060 return result;
1061 }
1062 /* It's either not present, or not implemented.
1063 Emulate using FindFirstFile. */
1064 if (level != GetFileExInfoStandard) {
1065 SetLastError(ERROR_INVALID_PARAMETER);
1066 return FALSE;
1067 }
1068 /* Use GetFileAttributes to validate that the file name
1069 does not contain wildcards (which FindFirstFile would
1070 accept). */
1071 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
1072 return FALSE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001073 return attributes_from_dir(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +00001074}
1075
1076static BOOL WINAPI
1077Py_GetFileAttributesExW(LPCWSTR pszFile,
1078 GET_FILEEX_INFO_LEVELS level,
1079 LPVOID pv)
1080{
1081 BOOL result;
Thomas Wouters89f507f2006-12-13 04:49:30 +00001082 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
1083 /* First try to use the system's implementation, if that is
1084 available and either succeeds to gives an error other than
1085 that it isn't implemented. */
1086 check_gfax();
1087 if (gfaxa) {
1088 result = gfaxw(pszFile, level, pv);
1089 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
1090 return result;
1091 }
1092 /* It's either not present, or not implemented.
1093 Emulate using FindFirstFile. */
1094 if (level != GetFileExInfoStandard) {
1095 SetLastError(ERROR_INVALID_PARAMETER);
1096 return FALSE;
1097 }
1098 /* Use GetFileAttributes to validate that the file name
1099 does not contain wildcards (which FindFirstFile would
1100 accept). */
1101 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
1102 return FALSE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001103 return attributes_from_dir_w(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +00001104}
1105
Martin v. Löwis14694662006-02-03 12:54:16 +00001106static int
1107win32_stat(const char* path, struct win32_stat *result)
1108{
1109 WIN32_FILE_ATTRIBUTE_DATA info;
1110 int code;
1111 char *dot;
1112 /* XXX not supported on Win95 and NT 3.x */
Thomas Wouters89f507f2006-12-13 04:49:30 +00001113 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
Guido van Rossumd8faa362007-04-27 19:54:29 +00001114 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1115 /* Protocol violation: we explicitly clear errno, instead of
1116 setting it to a POSIX error. Callers should use GetLastError. */
1117 errno = 0;
1118 return -1;
1119 } else {
1120 /* Could not get attributes on open file. Fall back to
1121 reading the directory. */
1122 if (!attributes_from_dir(path, &info)) {
1123 /* Very strange. This should not fail now */
1124 errno = 0;
1125 return -1;
1126 }
1127 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001128 }
1129 code = attribute_data_to_stat(&info, result);
1130 if (code != 0)
1131 return code;
1132 /* Set S_IFEXEC if it is an .exe, .bat, ... */
1133 dot = strrchr(path, '.');
1134 if (dot) {
1135 if (stricmp(dot, ".bat") == 0 ||
1136 stricmp(dot, ".cmd") == 0 ||
1137 stricmp(dot, ".exe") == 0 ||
1138 stricmp(dot, ".com") == 0)
1139 result->st_mode |= 0111;
1140 }
1141 return code;
1142}
1143
1144static int
1145win32_wstat(const wchar_t* path, struct win32_stat *result)
1146{
1147 int code;
1148 const wchar_t *dot;
1149 WIN32_FILE_ATTRIBUTE_DATA info;
1150 /* XXX not supported on Win95 and NT 3.x */
Thomas Wouters89f507f2006-12-13 04:49:30 +00001151 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
Guido van Rossumd8faa362007-04-27 19:54:29 +00001152 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1153 /* Protocol violation: we explicitly clear errno, instead of
1154 setting it to a POSIX error. Callers should use GetLastError. */
1155 errno = 0;
1156 return -1;
1157 } else {
1158 /* Could not get attributes on open file. Fall back to
1159 reading the directory. */
1160 if (!attributes_from_dir_w(path, &info)) {
1161 /* Very strange. This should not fail now */
1162 errno = 0;
1163 return -1;
1164 }
1165 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001166 }
1167 code = attribute_data_to_stat(&info, result);
1168 if (code < 0)
1169 return code;
1170 /* Set IFEXEC if it is an .exe, .bat, ... */
1171 dot = wcsrchr(path, '.');
1172 if (dot) {
1173 if (_wcsicmp(dot, L".bat") == 0 ||
1174 _wcsicmp(dot, L".cmd") == 0 ||
1175 _wcsicmp(dot, L".exe") == 0 ||
1176 _wcsicmp(dot, L".com") == 0)
1177 result->st_mode |= 0111;
1178 }
1179 return code;
1180}
1181
1182static int
1183win32_fstat(int file_number, struct win32_stat *result)
1184{
1185 BY_HANDLE_FILE_INFORMATION info;
1186 HANDLE h;
1187 int type;
1188
1189 h = (HANDLE)_get_osfhandle(file_number);
1190
1191 /* Protocol violation: we explicitly clear errno, instead of
1192 setting it to a POSIX error. Callers should use GetLastError. */
1193 errno = 0;
1194
1195 if (h == INVALID_HANDLE_VALUE) {
1196 /* This is really a C library error (invalid file handle).
1197 We set the Win32 error to the closes one matching. */
1198 SetLastError(ERROR_INVALID_HANDLE);
1199 return -1;
1200 }
1201 memset(result, 0, sizeof(*result));
1202
1203 type = GetFileType(h);
1204 if (type == FILE_TYPE_UNKNOWN) {
1205 DWORD error = GetLastError();
1206 if (error != 0) {
1207 return -1;
1208 }
1209 /* else: valid but unknown file */
1210 }
1211
1212 if (type != FILE_TYPE_DISK) {
1213 if (type == FILE_TYPE_CHAR)
1214 result->st_mode = _S_IFCHR;
1215 else if (type == FILE_TYPE_PIPE)
1216 result->st_mode = _S_IFIFO;
1217 return 0;
1218 }
1219
1220 if (!GetFileInformationByHandle(h, &info)) {
1221 return -1;
1222 }
1223
1224 /* similar to stat() */
1225 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1226 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1227 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1228 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1229 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1230 /* specific to fstat() */
1231 result->st_nlink = info.nNumberOfLinks;
1232 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1233 return 0;
1234}
1235
1236#endif /* MS_WINDOWS */
1237
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001238PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001239"stat_result: Result from stat or lstat.\n\n\
1240This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001241 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001242or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1243\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001244Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1245or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001246\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001247See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001248
1249static PyStructSequence_Field stat_result_fields[] = {
1250 {"st_mode", "protection bits"},
1251 {"st_ino", "inode"},
1252 {"st_dev", "device"},
1253 {"st_nlink", "number of hard links"},
1254 {"st_uid", "user ID of owner"},
1255 {"st_gid", "group ID of owner"},
1256 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001257 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1258 {NULL, "integer time of last access"},
1259 {NULL, "integer time of last modification"},
1260 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001261 {"st_atime", "time of last access"},
1262 {"st_mtime", "time of last modification"},
1263 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001264#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001265 {"st_blksize", "blocksize for filesystem I/O"},
1266#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001267#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001268 {"st_blocks", "number of blocks allocated"},
1269#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001270#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001271 {"st_rdev", "device type (if inode device)"},
1272#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001273#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1274 {"st_flags", "user defined flags for file"},
1275#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001276#ifdef HAVE_STRUCT_STAT_ST_GEN
1277 {"st_gen", "generation number"},
1278#endif
1279#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1280 {"st_birthtime", "time of creation"},
1281#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001282 {0}
1283};
1284
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001285#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001286#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001287#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001288#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001289#endif
1290
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001291#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001292#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1293#else
1294#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1295#endif
1296
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001297#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001298#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1299#else
1300#define ST_RDEV_IDX ST_BLOCKS_IDX
1301#endif
1302
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001303#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1304#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1305#else
1306#define ST_FLAGS_IDX ST_RDEV_IDX
1307#endif
1308
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001309#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001310#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001311#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001312#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001313#endif
1314
1315#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1316#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1317#else
1318#define ST_BIRTHTIME_IDX ST_GEN_IDX
1319#endif
1320
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001321static PyStructSequence_Desc stat_result_desc = {
1322 "stat_result", /* name */
1323 stat_result__doc__, /* doc */
1324 stat_result_fields,
1325 10
1326};
1327
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001328PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001329"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1330This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001331 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001332or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001333\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001334See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001335
1336static PyStructSequence_Field statvfs_result_fields[] = {
1337 {"f_bsize", },
1338 {"f_frsize", },
1339 {"f_blocks", },
1340 {"f_bfree", },
1341 {"f_bavail", },
1342 {"f_files", },
1343 {"f_ffree", },
1344 {"f_favail", },
1345 {"f_flag", },
1346 {"f_namemax",},
1347 {0}
1348};
1349
1350static PyStructSequence_Desc statvfs_result_desc = {
1351 "statvfs_result", /* name */
1352 statvfs_result__doc__, /* doc */
1353 statvfs_result_fields,
1354 10
1355};
1356
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001357static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001358static PyTypeObject StatResultType;
1359static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001360static newfunc structseq_new;
1361
1362static PyObject *
1363statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1364{
1365 PyStructSequence *result;
1366 int i;
1367
1368 result = (PyStructSequence*)structseq_new(type, args, kwds);
1369 if (!result)
1370 return NULL;
1371 /* If we have been initialized from a tuple,
1372 st_?time might be set to None. Initialize it
1373 from the int slots. */
1374 for (i = 7; i <= 9; i++) {
1375 if (result->ob_item[i+3] == Py_None) {
1376 Py_DECREF(Py_None);
1377 Py_INCREF(result->ob_item[i]);
1378 result->ob_item[i+3] = result->ob_item[i];
1379 }
1380 }
1381 return (PyObject*)result;
1382}
1383
1384
1385
1386/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001387static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001388
1389PyDoc_STRVAR(stat_float_times__doc__,
1390"stat_float_times([newval]) -> oldval\n\n\
1391Determine whether os.[lf]stat represents time stamps as float objects.\n\
1392If newval is True, future calls to stat() return floats, if it is False,\n\
1393future calls return ints. \n\
1394If newval is omitted, return the current setting.\n");
1395
1396static PyObject*
1397stat_float_times(PyObject* self, PyObject *args)
1398{
1399 int newval = -1;
1400 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1401 return NULL;
1402 if (newval == -1)
1403 /* Return old value */
1404 return PyBool_FromLong(_stat_float_times);
1405 _stat_float_times = newval;
1406 Py_INCREF(Py_None);
1407 return Py_None;
1408}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001409
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001410static void
1411fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1412{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001413 PyObject *fval,*ival;
1414#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001415 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001416#else
Christian Heimes217cfd12007-12-02 14:31:20 +00001417 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001418#endif
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001419 if (!ival)
1420 return;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001421 if (_stat_float_times) {
1422 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1423 } else {
1424 fval = ival;
1425 Py_INCREF(fval);
1426 }
1427 PyStructSequence_SET_ITEM(v, index, ival);
1428 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001429}
1430
Tim Peters5aa91602002-01-30 05:46:57 +00001431/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001432 (used by posix_stat() and posix_fstat()) */
1433static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001434_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001435{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001436 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001437 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001438 if (v == NULL)
1439 return NULL;
1440
Christian Heimes217cfd12007-12-02 14:31:20 +00001441 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001442#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001443 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001444 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001445#else
Christian Heimes217cfd12007-12-02 14:31:20 +00001446 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001447#endif
1448#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001449 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001450 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001451#else
Christian Heimes217cfd12007-12-02 14:31:20 +00001452 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001453#endif
Christian Heimes217cfd12007-12-02 14:31:20 +00001454 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1455 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1456 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001457#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001458 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001459 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001460#else
Christian Heimes217cfd12007-12-02 14:31:20 +00001461 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001462#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001463
Martin v. Löwis14694662006-02-03 12:54:16 +00001464#if defined(HAVE_STAT_TV_NSEC)
1465 ansec = st->st_atim.tv_nsec;
1466 mnsec = st->st_mtim.tv_nsec;
1467 cnsec = st->st_ctim.tv_nsec;
1468#elif defined(HAVE_STAT_TV_NSEC2)
1469 ansec = st->st_atimespec.tv_nsec;
1470 mnsec = st->st_mtimespec.tv_nsec;
1471 cnsec = st->st_ctimespec.tv_nsec;
1472#elif defined(HAVE_STAT_NSEC)
1473 ansec = st->st_atime_nsec;
1474 mnsec = st->st_mtime_nsec;
1475 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001476#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001477 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001478#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001479 fill_time(v, 7, st->st_atime, ansec);
1480 fill_time(v, 8, st->st_mtime, mnsec);
1481 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001482
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001483#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001484 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001485 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001486#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001487#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001488 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001489 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001490#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001491#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001492 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001493 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001494#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001495#ifdef HAVE_STRUCT_STAT_ST_GEN
1496 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001497 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001498#endif
1499#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1500 {
1501 PyObject *val;
1502 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001503 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001504#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001505 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001506#else
1507 bnsec = 0;
1508#endif
1509 if (_stat_float_times) {
1510 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1511 } else {
Christian Heimes217cfd12007-12-02 14:31:20 +00001512 val = PyLong_FromLong((long)bsec);
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001513 }
1514 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1515 val);
1516 }
1517#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001518#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1519 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001520 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001521#endif
Fred Drake699f3522000-06-29 21:12:41 +00001522
1523 if (PyErr_Occurred()) {
1524 Py_DECREF(v);
1525 return NULL;
1526 }
1527
1528 return v;
1529}
1530
Martin v. Löwisd8948722004-06-02 09:57:56 +00001531#ifdef MS_WINDOWS
1532
1533/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1534 where / can be used in place of \ and the trailing slash is optional.
1535 Both SERVER and SHARE must have at least one character.
1536*/
1537
1538#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1539#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001540#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001541#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001542#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001543
Tim Peters4ad82172004-08-30 17:02:04 +00001544static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001545IsUNCRootA(char *path, int pathlen)
1546{
1547 #define ISSLASH ISSLASHA
1548
1549 int i, share;
1550
1551 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1552 /* minimum UNCRoot is \\x\y */
1553 return FALSE;
1554 for (i = 2; i < pathlen ; i++)
1555 if (ISSLASH(path[i])) break;
1556 if (i == 2 || i == pathlen)
1557 /* do not allow \\\SHARE or \\SERVER */
1558 return FALSE;
1559 share = i+1;
1560 for (i = share; i < pathlen; i++)
1561 if (ISSLASH(path[i])) break;
1562 return (i != share && (i == pathlen || i == pathlen-1));
1563
1564 #undef ISSLASH
1565}
1566
1567#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001568static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001569IsUNCRootW(Py_UNICODE *path, int pathlen)
1570{
1571 #define ISSLASH ISSLASHW
1572
1573 int i, share;
1574
1575 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1576 /* minimum UNCRoot is \\x\y */
1577 return FALSE;
1578 for (i = 2; i < pathlen ; i++)
1579 if (ISSLASH(path[i])) break;
1580 if (i == 2 || i == pathlen)
1581 /* do not allow \\\SHARE or \\SERVER */
1582 return FALSE;
1583 share = i+1;
1584 for (i = share; i < pathlen; i++)
1585 if (ISSLASH(path[i])) break;
1586 return (i != share && (i == pathlen || i == pathlen-1));
1587
1588 #undef ISSLASH
1589}
1590#endif /* Py_WIN_WIDE_FILENAMES */
1591#endif /* MS_WINDOWS */
1592
Barry Warsaw53699e91996-12-10 23:23:01 +00001593static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001594posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001595 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001596#ifdef __VMS
1597 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1598#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001599 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001600#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001601 char *wformat,
1602 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001603{
Fred Drake699f3522000-06-29 21:12:41 +00001604 STRUCT_STAT st;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001605 PyObject *opath;
1606 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001607 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001608 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001609
1610#ifdef Py_WIN_WIDE_FILENAMES
1611 /* If on wide-character-capable OS see if argument
1612 is Unicode and if so use wide API. */
1613 if (unicode_file_names()) {
1614 PyUnicodeObject *po;
1615 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001616 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1617
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001618 Py_BEGIN_ALLOW_THREADS
1619 /* PyUnicode_AS_UNICODE result OK without
1620 thread lock as it is a simple dereference. */
1621 res = wstatfunc(wpath, &st);
1622 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001623
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001624 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001625 return win32_error_unicode("stat", wpath);
1626 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001627 }
1628 /* Drop the argument parsing error as narrow strings
1629 are also valid. */
1630 PyErr_Clear();
1631 }
1632#endif
1633
Tim Peters5aa91602002-01-30 05:46:57 +00001634 if (!PyArg_ParseTuple(args, format,
Martin v. Löwis011e8422009-05-05 04:43:17 +00001635 PyUnicode_FSConverter, &opath))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001636 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001637 path = bytes2str(opath, 1);
Barry Warsaw53699e91996-12-10 23:23:01 +00001638 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001639 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001640 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001641
1642 if (res != 0) {
1643#ifdef MS_WINDOWS
Martin v. Löwis011e8422009-05-05 04:43:17 +00001644 result = win32_error("stat", path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001645#else
Martin v. Löwis011e8422009-05-05 04:43:17 +00001646 result = posix_error_with_filename(path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001647#endif
1648 }
1649 else
1650 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001651
Martin v. Löwis011e8422009-05-05 04:43:17 +00001652 release_bytes(opath);
Martin v. Löwis14694662006-02-03 12:54:16 +00001653 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001654}
1655
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001656/* POSIX methods */
1657
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001658PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001659"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001660Use the real uid/gid to test for access to a path. Note that most\n\
1661operations will use the effective uid/gid, therefore this routine can\n\
1662be used in a suid/sgid environment to test if the invoking user has the\n\
1663specified access to the path. The mode argument can be F_OK to test\n\
1664existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001665
1666static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001667posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001668{
Martin v. Löwis011e8422009-05-05 04:43:17 +00001669 PyObject *opath;
Guido van Rossum015f22a1999-01-06 22:52:38 +00001670 char *path;
1671 int mode;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001672
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001673#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001674 DWORD attr;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001675 if (unicode_file_names()) {
1676 PyUnicodeObject *po;
1677 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1678 Py_BEGIN_ALLOW_THREADS
1679 /* PyUnicode_AS_UNICODE OK without thread lock as
1680 it is a simple dereference. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001681 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001682 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001683 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001684 }
1685 /* Drop the argument parsing error as narrow strings
1686 are also valid. */
1687 PyErr_Clear();
1688 }
Martin v. Löwis011e8422009-05-05 04:43:17 +00001689 if (!PyArg_ParseTuple(args, "O&i:access",
1690 PyUnicode_FSConverter, &opath, &mode))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001691 return 0;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001692 path = bytes2str(opath, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001693 Py_BEGIN_ALLOW_THREADS
1694 attr = GetFileAttributesA(path);
1695 Py_END_ALLOW_THREADS
Martin v. Löwis011e8422009-05-05 04:43:17 +00001696 release_bytes(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001697finish:
1698 if (attr == 0xFFFFFFFF)
1699 /* File does not exist, or cannot read attributes */
1700 return PyBool_FromLong(0);
1701 /* Access is possible if either write access wasn't requested, or
Guido van Rossumb00324f2007-12-04 01:13:14 +00001702 the file isn't read-only, or if it's a directory, as there are
1703 no read-only directories on Windows. */
1704 return PyBool_FromLong(!(mode & 2)
1705 || !(attr & FILE_ATTRIBUTE_READONLY)
1706 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001707#else
1708 int res;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001709 if (!PyArg_ParseTuple(args, "O&i:access",
1710 PyUnicode_FSConverter, &opath, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001711 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001712 path = bytes2str(opath, 1);
Guido van Rossum015f22a1999-01-06 22:52:38 +00001713 Py_BEGIN_ALLOW_THREADS
1714 res = access(path, mode);
1715 Py_END_ALLOW_THREADS
Martin v. Löwis011e8422009-05-05 04:43:17 +00001716 release_bytes(opath);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001717 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001718#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001719}
1720
Guido van Rossumd371ff11999-01-25 16:12:23 +00001721#ifndef F_OK
1722#define F_OK 0
1723#endif
1724#ifndef R_OK
1725#define R_OK 4
1726#endif
1727#ifndef W_OK
1728#define W_OK 2
1729#endif
1730#ifndef X_OK
1731#define X_OK 1
1732#endif
1733
1734#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001735PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001736"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001737Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001738
1739static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001740posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001741{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001742 int id;
1743 char *ret;
1744
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001745 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001746 return NULL;
1747
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001748#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001749 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001750 if (id == 0) {
1751 ret = ttyname();
1752 }
1753 else {
1754 ret = NULL;
1755 }
1756#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001757 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001758#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001759 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001760 return posix_error();
Neal Norwitz93c56822007-08-26 07:10:06 +00001761 return PyUnicode_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001762}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001763#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001764
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001765#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001766PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001767"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001768Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001769
1770static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001771posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001772{
1773 char *ret;
1774 char buffer[L_ctermid];
1775
Greg Wardb48bc172000-03-01 21:51:56 +00001776#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001777 ret = ctermid_r(buffer);
1778#else
1779 ret = ctermid(buffer);
1780#endif
1781 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001782 return posix_error();
Neal Norwitz93c56822007-08-26 07:10:06 +00001783 return PyUnicode_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001784}
1785#endif
1786
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001787PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001788"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001789Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001790
Barry Warsaw53699e91996-12-10 23:23:01 +00001791static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001792posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001793{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001794#ifdef MS_WINDOWS
Amaury Forgeot d'Arcc72ef8b2008-10-03 18:38:26 +00001795 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001796#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Martin v. Löwis011e8422009-05-05 04:43:17 +00001797 return posix_1str(args, "O&:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001798#elif defined(__VMS)
Martin v. Löwis011e8422009-05-05 04:43:17 +00001799 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001800#else
Martin v. Löwis011e8422009-05-05 04:43:17 +00001801 return posix_1str(args, "O&:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001802#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001803}
1804
Fred Drake4d1e64b2002-04-15 19:40:07 +00001805#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001806PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001807"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001808Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001809opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001810
1811static PyObject *
1812posix_fchdir(PyObject *self, PyObject *fdobj)
1813{
1814 return posix_fildes(fdobj, fchdir);
1815}
1816#endif /* HAVE_FCHDIR */
1817
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001818
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001819PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001820"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001821Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001822
Barry Warsaw53699e91996-12-10 23:23:01 +00001823static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001824posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001825{
Martin v. Löwis011e8422009-05-05 04:43:17 +00001826 PyObject *opath = NULL;
Mark Hammondef8b6542001-05-13 08:04:26 +00001827 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001828 int i;
1829 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001830#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001831 DWORD attr;
Mark Hammond817c9292003-12-03 01:22:38 +00001832 if (unicode_file_names()) {
1833 PyUnicodeObject *po;
1834 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1835 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001836 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1837 if (attr != 0xFFFFFFFF) {
1838 if (i & _S_IWRITE)
1839 attr &= ~FILE_ATTRIBUTE_READONLY;
1840 else
1841 attr |= FILE_ATTRIBUTE_READONLY;
1842 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1843 }
1844 else
1845 res = 0;
Mark Hammond817c9292003-12-03 01:22:38 +00001846 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001847 if (!res)
1848 return win32_error_unicode("chmod",
Mark Hammond817c9292003-12-03 01:22:38 +00001849 PyUnicode_AS_UNICODE(po));
1850 Py_INCREF(Py_None);
1851 return Py_None;
1852 }
1853 /* Drop the argument parsing error as narrow strings
1854 are also valid. */
1855 PyErr_Clear();
1856 }
Martin v. Löwis011e8422009-05-05 04:43:17 +00001857 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1858 &opath, &i))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001859 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001860 path = bytes2str(opath, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001861 Py_BEGIN_ALLOW_THREADS
1862 attr = GetFileAttributesA(path);
1863 if (attr != 0xFFFFFFFF) {
1864 if (i & _S_IWRITE)
1865 attr &= ~FILE_ATTRIBUTE_READONLY;
1866 else
1867 attr |= FILE_ATTRIBUTE_READONLY;
1868 res = SetFileAttributesA(path, attr);
1869 }
1870 else
1871 res = 0;
1872 Py_END_ALLOW_THREADS
1873 if (!res) {
1874 win32_error("chmod", path);
Martin v. Löwis011e8422009-05-05 04:43:17 +00001875 release_bytes(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001876 return NULL;
1877 }
Martin v. Löwis011e8422009-05-05 04:43:17 +00001878 release_bytes(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001879 Py_INCREF(Py_None);
1880 return Py_None;
1881#else /* Py_WIN_WIDE_FILENAMES */
Martin v. Löwis011e8422009-05-05 04:43:17 +00001882 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1883 &opath, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001884 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001885 path = bytes2str(opath, 1);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001886 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001887 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001888 Py_END_ALLOW_THREADS
1889 if (res < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +00001890 return posix_error_with_allocated_filename(opath);
1891 release_bytes(opath);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001892 Py_INCREF(Py_None);
1893 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001894#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001895}
1896
Christian Heimes4e30a842007-11-30 22:12:06 +00001897#ifdef HAVE_FCHMOD
1898PyDoc_STRVAR(posix_fchmod__doc__,
1899"fchmod(fd, mode)\n\n\
1900Change the access permissions of the file given by file\n\
1901descriptor fd.");
1902
1903static PyObject *
1904posix_fchmod(PyObject *self, PyObject *args)
1905{
1906 int fd, mode, res;
1907 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1908 return NULL;
1909 Py_BEGIN_ALLOW_THREADS
1910 res = fchmod(fd, mode);
1911 Py_END_ALLOW_THREADS
1912 if (res < 0)
1913 return posix_error();
1914 Py_RETURN_NONE;
1915}
1916#endif /* HAVE_FCHMOD */
1917
1918#ifdef HAVE_LCHMOD
1919PyDoc_STRVAR(posix_lchmod__doc__,
1920"lchmod(path, mode)\n\n\
1921Change the access permissions of a file. If path is a symlink, this\n\
1922affects the link itself rather than the target.");
1923
1924static PyObject *
1925posix_lchmod(PyObject *self, PyObject *args)
1926{
Martin v. Löwis011e8422009-05-05 04:43:17 +00001927 PyObject *opath;
1928 char *path;
Christian Heimes4e30a842007-11-30 22:12:06 +00001929 int i;
1930 int res;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001931 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
1932 &opath, &i))
Christian Heimes4e30a842007-11-30 22:12:06 +00001933 return NULL;
Eric Smith86a05ec2009-05-05 13:07:30 +00001934 path = bytes2str(opath, 1);
Christian Heimes4e30a842007-11-30 22:12:06 +00001935 Py_BEGIN_ALLOW_THREADS
1936 res = lchmod(path, i);
1937 Py_END_ALLOW_THREADS
1938 if (res < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +00001939 return posix_error_with_allocated_filename(opath);
1940 release_bytes(opath);
Christian Heimes4e30a842007-11-30 22:12:06 +00001941 Py_RETURN_NONE;
1942}
1943#endif /* HAVE_LCHMOD */
1944
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001945
Thomas Wouterscf297e42007-02-23 15:07:44 +00001946#ifdef HAVE_CHFLAGS
1947PyDoc_STRVAR(posix_chflags__doc__,
1948"chflags(path, flags)\n\n\
1949Set file flags.");
1950
1951static PyObject *
1952posix_chflags(PyObject *self, PyObject *args)
1953{
Martin v. Löwis011e8422009-05-05 04:43:17 +00001954 PyObject *opath;
Thomas Wouterscf297e42007-02-23 15:07:44 +00001955 char *path;
1956 unsigned long flags;
1957 int res;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001958 if (!PyArg_ParseTuple(args, "O&k:chflags",
1959 PyUnicode_FSConverter, &opath, &flags))
Thomas Wouterscf297e42007-02-23 15:07:44 +00001960 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001961 path = bytes2str(opath, 1);
Thomas Wouterscf297e42007-02-23 15:07:44 +00001962 Py_BEGIN_ALLOW_THREADS
1963 res = chflags(path, flags);
1964 Py_END_ALLOW_THREADS
1965 if (res < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +00001966 return posix_error_with_allocated_filename(opath);
1967 release_bytes(opath);
Thomas Wouterscf297e42007-02-23 15:07:44 +00001968 Py_INCREF(Py_None);
1969 return Py_None;
1970}
1971#endif /* HAVE_CHFLAGS */
1972
1973#ifdef HAVE_LCHFLAGS
1974PyDoc_STRVAR(posix_lchflags__doc__,
1975"lchflags(path, flags)\n\n\
1976Set file flags.\n\
1977This function will not follow symbolic links.");
1978
1979static PyObject *
1980posix_lchflags(PyObject *self, PyObject *args)
1981{
Martin v. Löwis011e8422009-05-05 04:43:17 +00001982 PyObject *opath;
Thomas Wouterscf297e42007-02-23 15:07:44 +00001983 char *path;
1984 unsigned long flags;
1985 int res;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001986 if (!PyArg_ParseTuple(args, "O&k:lchflags",
Martin v. Löwis4adbc342009-05-05 17:17:55 +00001987 PyUnicode_FSConverter, &opath, &flags))
Thomas Wouterscf297e42007-02-23 15:07:44 +00001988 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001989 path = bytes2str(opath, 1);
Thomas Wouterscf297e42007-02-23 15:07:44 +00001990 Py_BEGIN_ALLOW_THREADS
1991 res = lchflags(path, flags);
1992 Py_END_ALLOW_THREADS
1993 if (res < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +00001994 return posix_error_with_allocated_filename(opath);
1995 release_bytes(opath);
Thomas Wouterscf297e42007-02-23 15:07:44 +00001996 Py_INCREF(Py_None);
1997 return Py_None;
1998}
1999#endif /* HAVE_LCHFLAGS */
2000
Martin v. Löwis244edc82001-10-04 22:44:26 +00002001#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002002PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002003"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002004Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002005
2006static PyObject *
2007posix_chroot(PyObject *self, PyObject *args)
2008{
Martin v. Löwis011e8422009-05-05 04:43:17 +00002009 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002010}
2011#endif
2012
Guido van Rossum21142a01999-01-08 21:05:37 +00002013#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002014PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002015"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002016force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002017
2018static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002019posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002020{
Fred Drake4d1e64b2002-04-15 19:40:07 +00002021 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002022}
2023#endif /* HAVE_FSYNC */
2024
2025#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002026
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002027#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002028extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2029#endif
2030
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002031PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002032"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002033force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002034 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002035
2036static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002037posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002038{
Fred Drake4d1e64b2002-04-15 19:40:07 +00002039 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002040}
2041#endif /* HAVE_FDATASYNC */
2042
2043
Fredrik Lundh10723342000-07-10 16:38:09 +00002044#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002045PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002046"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002047Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002048
Barry Warsaw53699e91996-12-10 23:23:01 +00002049static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002050posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002051{
Martin v. Löwis011e8422009-05-05 04:43:17 +00002052 PyObject *opath;
2053 char *path;
Christian Heimesd5e2b6f2008-03-19 21:50:51 +00002054 long uid, gid;
Fredrik Lundh44328e62000-07-10 15:59:30 +00002055 int res;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002056 if (!PyArg_ParseTuple(args, "O&ll:chown",
2057 PyUnicode_FSConverter, &opath,
Mark Hammondef8b6542001-05-13 08:04:26 +00002058 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00002059 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002060 path = bytes2str(opath, 1);
Fredrik Lundh44328e62000-07-10 15:59:30 +00002061 Py_BEGIN_ALLOW_THREADS
2062 res = chown(path, (uid_t) uid, (gid_t) gid);
2063 Py_END_ALLOW_THREADS
2064 if (res < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +00002065 return posix_error_with_allocated_filename(opath);
2066 release_bytes(opath);
Fredrik Lundh44328e62000-07-10 15:59:30 +00002067 Py_INCREF(Py_None);
2068 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002069}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002070#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002071
Christian Heimes4e30a842007-11-30 22:12:06 +00002072#ifdef HAVE_FCHOWN
2073PyDoc_STRVAR(posix_fchown__doc__,
2074"fchown(fd, uid, gid)\n\n\
2075Change the owner and group id of the file given by file descriptor\n\
2076fd to the numeric uid and gid.");
2077
2078static PyObject *
2079posix_fchown(PyObject *self, PyObject *args)
2080{
2081 int fd, uid, gid;
2082 int res;
2083 if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid))
2084 return NULL;
2085 Py_BEGIN_ALLOW_THREADS
2086 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2087 Py_END_ALLOW_THREADS
2088 if (res < 0)
2089 return posix_error();
2090 Py_RETURN_NONE;
2091}
2092#endif /* HAVE_FCHOWN */
2093
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002094#ifdef HAVE_LCHOWN
2095PyDoc_STRVAR(posix_lchown__doc__,
2096"lchown(path, uid, gid)\n\n\
2097Change the owner and group id of path to the numeric uid and gid.\n\
2098This function will not follow symbolic links.");
2099
2100static PyObject *
2101posix_lchown(PyObject *self, PyObject *args)
2102{
Martin v. Löwis011e8422009-05-05 04:43:17 +00002103 PyObject *opath;
2104 char *path;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002105 int uid, gid;
2106 int res;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002107 if (!PyArg_ParseTuple(args, "O&ii:lchown",
2108 PyUnicode_FSConverter, &opath,
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002109 &uid, &gid))
2110 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002111 path = bytes2str(opath, 1);
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002112 Py_BEGIN_ALLOW_THREADS
2113 res = lchown(path, (uid_t) uid, (gid_t) gid);
2114 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00002115 if (res < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +00002116 return posix_error_with_allocated_filename(opath);
2117 release_bytes(opath);
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002118 Py_INCREF(Py_None);
2119 return Py_None;
2120}
2121#endif /* HAVE_LCHOWN */
2122
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002123
Guido van Rossum36bc6801995-06-14 22:54:23 +00002124#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002125static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002126posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002127{
2128 char buf[1026];
2129 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002130
2131#ifdef Py_WIN_WIDE_FILENAMES
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002132 if (!use_bytes && unicode_file_names()) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002133 wchar_t wbuf[1026];
Thomas Wouters477c8d52006-05-27 19:21:47 +00002134 wchar_t *wbuf2 = wbuf;
2135 PyObject *resobj;
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002136 DWORD len;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002137 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002138 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2139 /* If the buffer is large enough, len does not include the
2140 terminating \0. If the buffer is too small, len includes
2141 the space needed for the terminator. */
2142 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2143 wbuf2 = malloc(len * sizeof(wchar_t));
2144 if (wbuf2)
2145 len = GetCurrentDirectoryW(len, wbuf2);
2146 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002147 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002148 if (!wbuf2) {
2149 PyErr_NoMemory();
2150 return NULL;
2151 }
2152 if (!len) {
2153 if (wbuf2 != wbuf) free(wbuf2);
2154 return win32_error("getcwdu", NULL);
2155 }
2156 resobj = PyUnicode_FromWideChar(wbuf2, len);
2157 if (wbuf2 != wbuf) free(wbuf2);
2158 return resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002159 }
2160#endif
2161
2162 Py_BEGIN_ALLOW_THREADS
2163#if defined(PYOS_OS2) && defined(PYCC_GCC)
2164 res = _getcwd2(buf, sizeof buf);
2165#else
2166 res = getcwd(buf, sizeof buf);
2167#endif
2168 Py_END_ALLOW_THREADS
2169 if (res == NULL)
2170 return posix_error();
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002171 if (use_bytes)
2172 return PyBytes_FromStringAndSize(buf, strlen(buf));
Martin v. Löwis43c57782009-05-10 08:15:24 +00002173 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"surrogateescape");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002174}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002175
2176PyDoc_STRVAR(posix_getcwd__doc__,
2177"getcwd() -> path\n\n\
2178Return a unicode string representing the current working directory.");
2179
2180static PyObject *
2181posix_getcwd_unicode(PyObject *self)
2182{
2183 return posix_getcwd(0);
2184}
2185
2186PyDoc_STRVAR(posix_getcwdb__doc__,
2187"getcwdb() -> path\n\n\
2188Return a bytes string representing the current working directory.");
2189
2190static PyObject *
2191posix_getcwd_bytes(PyObject *self)
2192{
2193 return posix_getcwd(1);
2194}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002195#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002196
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002197
Guido van Rossumb6775db1994-08-01 11:34:53 +00002198#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002199PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002200"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002201Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002202
Barry Warsaw53699e91996-12-10 23:23:01 +00002203static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002204posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002205{
Martin v. Löwis011e8422009-05-05 04:43:17 +00002206 return posix_2str(args, "O&O&:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002207}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002208#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002209
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002210
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002211PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002212"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002213Return a list containing the names of the entries in the directory.\n\
2214\n\
2215 path: path of directory to list\n\
2216\n\
2217The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002218entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002219
Barry Warsaw53699e91996-12-10 23:23:01 +00002220static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002221posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002222{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002223 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002224 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002225#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002226
Barry Warsaw53699e91996-12-10 23:23:01 +00002227 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002228 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002229 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002230 WIN32_FIND_DATA FileData;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002231 PyObject *opath;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002232 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00002233 char *bufptr = namebuf;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002234 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002235
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002236#ifdef Py_WIN_WIDE_FILENAMES
2237 /* If on wide-character-capable OS see if argument
2238 is Unicode and if so use wide API. */
2239 if (unicode_file_names()) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002240 PyObject *po;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002241 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2242 WIN32_FIND_DATAW wFileData;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002243 Py_UNICODE *wnamebuf;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002244 /* Overallocate for \\*.*\0 */
2245 len = PyUnicode_GET_SIZE(po);
2246 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2247 if (!wnamebuf) {
2248 PyErr_NoMemory();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002249 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002250 }
2251 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
Hirokazu Yamamotobbb9be72009-05-04 05:56:46 +00002252 if (len > 0) {
2253 Py_UNICODE wch = wnamebuf[len-1];
2254 if (wch != L'/' && wch != L'\\' && wch != L':')
2255 wnamebuf[len++] = L'\\';
2256 wcscpy(wnamebuf + len, L"*.*");
2257 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002258 if ((d = PyList_New(0)) == NULL) {
2259 free(wnamebuf);
2260 return NULL;
2261 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002262 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2263 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002264 int error = GetLastError();
2265 if (error == ERROR_FILE_NOT_FOUND) {
2266 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002267 return d;
2268 }
2269 Py_DECREF(d);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002270 win32_error_unicode("FindFirstFileW", wnamebuf);
2271 free(wnamebuf);
2272 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002273 }
2274 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002275 /* Skip over . and .. */
2276 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2277 wcscmp(wFileData.cFileName, L"..") != 0) {
2278 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2279 if (v == NULL) {
2280 Py_DECREF(d);
2281 d = NULL;
2282 break;
2283 }
2284 if (PyList_Append(d, v) != 0) {
2285 Py_DECREF(v);
2286 Py_DECREF(d);
2287 d = NULL;
2288 break;
2289 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002290 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002291 }
Georg Brandl622927b2006-03-07 12:48:03 +00002292 Py_BEGIN_ALLOW_THREADS
2293 result = FindNextFileW(hFindFile, &wFileData);
2294 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002295 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2296 it got to the end of the directory. */
2297 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2298 Py_DECREF(d);
2299 win32_error_unicode("FindNextFileW", wnamebuf);
2300 FindClose(hFindFile);
2301 free(wnamebuf);
2302 return NULL;
2303 }
Georg Brandl622927b2006-03-07 12:48:03 +00002304 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002305
2306 if (FindClose(hFindFile) == FALSE) {
2307 Py_DECREF(d);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002308 win32_error_unicode("FindClose", wnamebuf);
2309 free(wnamebuf);
2310 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002311 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002312 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002313 return d;
2314 }
2315 /* Drop the argument parsing error as narrow strings
2316 are also valid. */
2317 PyErr_Clear();
2318 }
2319#endif
2320
Martin v. Löwis011e8422009-05-05 04:43:17 +00002321 if (!PyArg_ParseTuple(args, "O&:listdir",
2322 PyUnicode_FSConverter, &opath))
Guido van Rossumb6775db1994-08-01 11:34:53 +00002323 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002324 if (PyObject_Size(opath)+1 > MAX_PATH) {
2325 PyErr_SetString(PyExc_ValueError, "path too long");
2326 Py_DECREF(opath);
2327 return NULL;
2328 }
2329 strcpy(namebuf, bytes2str(opath, 0));
2330 len = PyObject_Size(opath);
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002331 if (len > 0) {
2332 char ch = namebuf[len-1];
2333 if (ch != SEP && ch != ALTSEP && ch != ':')
2334 namebuf[len++] = '/';
Hirokazu Yamamotobbb9be72009-05-04 05:56:46 +00002335 strcpy(namebuf + len, "*.*");
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002336 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002337
Barry Warsaw53699e91996-12-10 23:23:01 +00002338 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002339 return NULL;
2340
2341 hFindFile = FindFirstFile(namebuf, &FileData);
2342 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002343 int error = GetLastError();
2344 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002345 return d;
2346 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002347 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002348 }
2349 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002350 /* Skip over . and .. */
2351 if (strcmp(FileData.cFileName, ".") != 0 &&
2352 strcmp(FileData.cFileName, "..") != 0) {
Christian Heimes72b710a2008-05-26 13:28:38 +00002353 v = PyBytes_FromString(FileData.cFileName);
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002354 if (v == NULL) {
2355 Py_DECREF(d);
2356 d = NULL;
2357 break;
2358 }
2359 if (PyList_Append(d, v) != 0) {
2360 Py_DECREF(v);
2361 Py_DECREF(d);
2362 d = NULL;
2363 break;
2364 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002365 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002366 }
Georg Brandl622927b2006-03-07 12:48:03 +00002367 Py_BEGIN_ALLOW_THREADS
2368 result = FindNextFile(hFindFile, &FileData);
2369 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002370 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2371 it got to the end of the directory. */
2372 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2373 Py_DECREF(d);
2374 win32_error("FindNextFile", namebuf);
2375 FindClose(hFindFile);
2376 return NULL;
2377 }
Georg Brandl622927b2006-03-07 12:48:03 +00002378 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002379
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002380 if (FindClose(hFindFile) == FALSE) {
2381 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002382 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002383 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002384
2385 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002386
Tim Peters0bb44a42000-09-15 07:44:49 +00002387#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002388
2389#ifndef MAX_PATH
2390#define MAX_PATH CCHMAXPATH
2391#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002392 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002393 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002394 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002395 PyObject *d, *v;
2396 char namebuf[MAX_PATH+5];
2397 HDIR hdir = 1;
2398 ULONG srchcnt = 1;
2399 FILEFINDBUF3 ep;
2400 APIRET rc;
2401
Martin v. Löwis011e8422009-05-05 04:43:17 +00002402 if (!PyArg_ParseTuple(args, "O&:listdir",
2403 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002404 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002405 name = bytes2str(oname);
2406 len = PyObject_Size(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002407 if (len >= MAX_PATH) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00002408 release_bytes(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002409 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002410 return NULL;
2411 }
2412 strcpy(namebuf, name);
2413 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002414 if (*pt == ALTSEP)
2415 *pt = SEP;
2416 if (namebuf[len-1] != SEP)
2417 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002418 strcpy(namebuf + len, "*.*");
2419
Neal Norwitz6c913782007-10-14 03:23:09 +00002420 if ((d = PyList_New(0)) == NULL) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00002421 release_bytes(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002422 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002423 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002424
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002425 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2426 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002427 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002428 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2429 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2430 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002431
2432 if (rc != NO_ERROR) {
2433 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002434 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002435 }
2436
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002437 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002438 do {
2439 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002440 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002441 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002442
2443 strcpy(namebuf, ep.achName);
2444
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002445 /* Leave Case of Name Alone -- In Native Form */
2446 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002447
Christian Heimes72b710a2008-05-26 13:28:38 +00002448 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002449 if (v == NULL) {
2450 Py_DECREF(d);
2451 d = NULL;
2452 break;
2453 }
2454 if (PyList_Append(d, v) != 0) {
2455 Py_DECREF(v);
2456 Py_DECREF(d);
2457 d = NULL;
2458 break;
2459 }
2460 Py_DECREF(v);
2461 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2462 }
2463
Martin v. Löwis011e8422009-05-05 04:43:17 +00002464 release_bytes(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002465 return d;
2466#else
Martin v. Löwis011e8422009-05-05 04:43:17 +00002467 PyObject *oname;
2468 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00002469 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002470 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002471 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00002472 int arg_is_unicode = 1;
2473
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002474 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002475 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2476 arg_is_unicode = 0;
2477 PyErr_Clear();
2478 }
Martin v. Löwis011e8422009-05-05 04:43:17 +00002479 if (!PyArg_ParseTuple(args, "O&:listdir", PyUnicode_FSConverter, &oname))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002480 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002481 name = bytes2str(oname, 1);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002482 if ((dirp = opendir(name)) == NULL) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00002483 return posix_error_with_allocated_filename(oname);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002484 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002485 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002486 closedir(dirp);
Martin v. Löwis011e8422009-05-05 04:43:17 +00002487 release_bytes(oname);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002488 return NULL;
2489 }
Georg Brandl622927b2006-03-07 12:48:03 +00002490 for (;;) {
Georg Brandl3dbca812008-07-23 16:10:53 +00002491 errno = 0;
Georg Brandl622927b2006-03-07 12:48:03 +00002492 Py_BEGIN_ALLOW_THREADS
2493 ep = readdir(dirp);
2494 Py_END_ALLOW_THREADS
Georg Brandl3dbca812008-07-23 16:10:53 +00002495 if (ep == NULL) {
2496 if (errno == 0) {
2497 break;
2498 } else {
2499 closedir(dirp);
2500 Py_DECREF(d);
Martin v. Löwis011e8422009-05-05 04:43:17 +00002501 return posix_error_with_allocated_filename(oname);
Georg Brandl3dbca812008-07-23 16:10:53 +00002502 }
2503 }
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002504 if (ep->d_name[0] == '.' &&
2505 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002506 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002507 continue;
Christian Heimes72b710a2008-05-26 13:28:38 +00002508 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002509 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002510 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002511 d = NULL;
2512 break;
2513 }
Just van Rossum96b1c902003-03-03 17:32:15 +00002514 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002515 PyObject *w;
2516
2517 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002518 Py_FileSystemDefaultEncoding,
Martin v. Löwis43c57782009-05-10 08:15:24 +00002519 "surrogateescape");
Martin v. Löwis011e8422009-05-05 04:43:17 +00002520 Py_DECREF(v);
2521 if (w != NULL)
Just van Rossum6a421832003-03-04 19:30:44 +00002522 v = w;
Just van Rossum6a421832003-03-04 19:30:44 +00002523 else {
Martin v. Löwis011e8422009-05-05 04:43:17 +00002524 /* Encoding failed to decode ASCII bytes.
2525 Raise exception. */
2526 Py_DECREF(d);
2527 d = NULL;
2528 break;
Just van Rossum46c97842003-02-25 21:42:15 +00002529 }
Just van Rossum46c97842003-02-25 21:42:15 +00002530 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002531 if (PyList_Append(d, v) != 0) {
2532 Py_DECREF(v);
2533 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002534 d = NULL;
2535 break;
2536 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002537 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002538 }
2539 closedir(dirp);
Martin v. Löwis011e8422009-05-05 04:43:17 +00002540 release_bytes(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002541
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002542 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002543
Tim Peters0bb44a42000-09-15 07:44:49 +00002544#endif /* which OS */
2545} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002546
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002547#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002548/* A helper function for abspath on win32 */
2549static PyObject *
2550posix__getfullpathname(PyObject *self, PyObject *args)
2551{
Martin v. Löwis011e8422009-05-05 04:43:17 +00002552 PyObject *opath;
2553 char *path;
Mark Hammondef8b6542001-05-13 08:04:26 +00002554 char outbuf[MAX_PATH*2];
2555 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002556#ifdef Py_WIN_WIDE_FILENAMES
2557 if (unicode_file_names()) {
2558 PyUnicodeObject *po;
2559 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
Benjamin Petersonf608c612008-11-16 18:33:53 +00002560 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2561 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002562 Py_UNICODE *wtemp;
Benjamin Petersonf608c612008-11-16 18:33:53 +00002563 DWORD result;
2564 PyObject *v;
2565 result = GetFullPathNameW(wpath,
2566 sizeof(woutbuf)/sizeof(woutbuf[0]),
2567 woutbuf, &wtemp);
2568 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2569 woutbufp = malloc(result * sizeof(Py_UNICODE));
2570 if (!woutbufp)
2571 return PyErr_NoMemory();
2572 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2573 }
2574 if (result)
2575 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2576 else
2577 v = win32_error_unicode("GetFullPathNameW", wpath);
2578 if (woutbufp != woutbuf)
2579 free(woutbufp);
2580 return v;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002581 }
2582 /* Drop the argument parsing error as narrow strings
2583 are also valid. */
2584 PyErr_Clear();
2585 }
2586#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002587 if (!PyArg_ParseTuple (args, "O&:_getfullpathname",
2588 PyUnicode_FSConverter, &opath))
Mark Hammondef8b6542001-05-13 08:04:26 +00002589 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002590 path = bytes2str(opath, 1);
2591 if (!GetFullPathName(path, sizeof(outbuf)/sizeof(outbuf[0]),
2592 outbuf, &temp)) {
2593 win32_error("GetFullPathName", path);
2594 release_bytes(opath);
2595 return NULL;
2596 }
2597 release_bytes(opath);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002598 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2599 return PyUnicode_Decode(outbuf, strlen(outbuf),
2600 Py_FileSystemDefaultEncoding, NULL);
2601 }
Christian Heimes72b710a2008-05-26 13:28:38 +00002602 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002603} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002604#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002605
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002606PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002607"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002608Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002609
Barry Warsaw53699e91996-12-10 23:23:01 +00002610static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002611posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002612{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002613 int res;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002614 PyObject *opath;
2615 char *path;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002616 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002617
2618#ifdef Py_WIN_WIDE_FILENAMES
2619 if (unicode_file_names()) {
2620 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00002621 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002622 Py_BEGIN_ALLOW_THREADS
2623 /* PyUnicode_AS_UNICODE OK without thread lock as
2624 it is a simple dereference. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002625 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002626 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002627 if (!res)
2628 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002629 Py_INCREF(Py_None);
2630 return Py_None;
2631 }
2632 /* Drop the argument parsing error as narrow strings
2633 are also valid. */
2634 PyErr_Clear();
2635 }
Martin v. Löwis011e8422009-05-05 04:43:17 +00002636 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2637 PyUnicode_FSConverter, &opath, &mode))
Thomas Wouters477c8d52006-05-27 19:21:47 +00002638 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002639 path = bytes2str(opath, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002640 Py_BEGIN_ALLOW_THREADS
2641 /* PyUnicode_AS_UNICODE OK without thread lock as
2642 it is a simple dereference. */
2643 res = CreateDirectoryA(path, NULL);
2644 Py_END_ALLOW_THREADS
2645 if (!res) {
2646 win32_error("mkdir", path);
Martin v. Löwis011e8422009-05-05 04:43:17 +00002647 release_bytes(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002648 return NULL;
2649 }
Martin v. Löwis011e8422009-05-05 04:43:17 +00002650 release_bytes(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002651 Py_INCREF(Py_None);
2652 return Py_None;
2653#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002654
Martin v. Löwis011e8422009-05-05 04:43:17 +00002655 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2656 PyUnicode_FSConverter, &opath, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002657 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002658 path = bytes2str(opath, 1);
Barry Warsaw53699e91996-12-10 23:23:01 +00002659 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002660#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002661 res = mkdir(path);
2662#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002663 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002664#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002665 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002666 if (res < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +00002667 return posix_error_with_allocated_filename(opath);
2668 release_bytes(opath);
Barry Warsaw53699e91996-12-10 23:23:01 +00002669 Py_INCREF(Py_None);
2670 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002671#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002672}
2673
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002674
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002675/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2676#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002677#include <sys/resource.h>
2678#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002679
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002680
2681#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002682PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002683"nice(inc) -> new_priority\n\n\
2684Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002685
Barry Warsaw53699e91996-12-10 23:23:01 +00002686static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002687posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002688{
2689 int increment, value;
2690
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002691 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002692 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002693
2694 /* There are two flavours of 'nice': one that returns the new
2695 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002696 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2697 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002698
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002699 If we are of the nice family that returns the new priority, we
2700 need to clear errno before the call, and check if errno is filled
2701 before calling posix_error() on a returnvalue of -1, because the
2702 -1 may be the actual new priority! */
2703
2704 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002705 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002706#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002707 if (value == 0)
2708 value = getpriority(PRIO_PROCESS, 0);
2709#endif
2710 if (value == -1 && errno != 0)
2711 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002712 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00002713 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002714}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002715#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002716
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002717PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002718"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002719Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002720
Barry Warsaw53699e91996-12-10 23:23:01 +00002721static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002722posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002723{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002724#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002725 PyObject *o1, *o2;
2726 char *p1, *p2;
2727 BOOL result;
2728 if (unicode_file_names()) {
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +00002729 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2730 goto error;
2731 if (!convert_to_unicode(&o1))
2732 goto error;
2733 if (!convert_to_unicode(&o2)) {
2734 Py_DECREF(o1);
2735 goto error;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002736 }
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +00002737 Py_BEGIN_ALLOW_THREADS
2738 result = MoveFileW(PyUnicode_AsUnicode(o1),
2739 PyUnicode_AsUnicode(o2));
2740 Py_END_ALLOW_THREADS
2741 Py_DECREF(o1);
2742 Py_DECREF(o2);
2743 if (!result)
2744 return win32_error("rename", NULL);
2745 Py_INCREF(Py_None);
2746 return Py_None;
2747error:
2748 PyErr_Clear();
Thomas Wouters477c8d52006-05-27 19:21:47 +00002749 }
2750 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2751 return NULL;
2752 Py_BEGIN_ALLOW_THREADS
2753 result = MoveFileA(p1, p2);
2754 Py_END_ALLOW_THREADS
2755 if (!result)
2756 return win32_error("rename", NULL);
2757 Py_INCREF(Py_None);
2758 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002759#else
Martin v. Löwis011e8422009-05-05 04:43:17 +00002760 return posix_2str(args, "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002761#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002762}
2763
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002764
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002765PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002766"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002767Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002768
Barry Warsaw53699e91996-12-10 23:23:01 +00002769static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002770posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002771{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002772#ifdef MS_WINDOWS
Amaury Forgeot d'Arcc72ef8b2008-10-03 18:38:26 +00002773 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002774#else
Martin v. Löwis011e8422009-05-05 04:43:17 +00002775 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002776#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002777}
2778
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002779
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002780PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002781"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002782Perform a stat system call on the given path.");
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_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002786{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002787#ifdef MS_WINDOWS
Martin v. Löwis011e8422009-05-05 04:43:17 +00002788 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002789#else
Martin v. Löwis011e8422009-05-05 04:43:17 +00002790 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002791#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002792}
2793
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002794
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002795#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002796PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002797"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002798Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002799
Barry Warsaw53699e91996-12-10 23:23:01 +00002800static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002801posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002802{
Guido van Rossumff4949e1992-08-05 19:58:53 +00002803 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002804#ifdef MS_WINDOWS
2805 wchar_t *command;
2806 if (!PyArg_ParseTuple(args, "u:system", &command))
2807 return NULL;
2808#else
2809 char *command;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002810 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002811 return NULL;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002812#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002813 Py_BEGIN_ALLOW_THREADS
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002814#ifdef MS_WINDOWS
2815 sts = _wsystem(command);
2816#else
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002817 sts = system(command);
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002818#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002819 Py_END_ALLOW_THREADS
Christian Heimes217cfd12007-12-02 14:31:20 +00002820 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002821}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002822#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002823
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002824
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002825PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002826"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002827Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002828
Barry Warsaw53699e91996-12-10 23:23:01 +00002829static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002830posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002831{
2832 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002833 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002834 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002835 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002836 if (i < 0)
2837 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00002838 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002839}
2840
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002841
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002842PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002843"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002844Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002845
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002846PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002847"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002848Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002849
Barry Warsaw53699e91996-12-10 23:23:01 +00002850static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002851posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002852{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002853#ifdef MS_WINDOWS
Amaury Forgeot d'Arcc72ef8b2008-10-03 18:38:26 +00002854 return win32_1str(args, "remove", "y:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002855#else
Martin v. Löwis011e8422009-05-05 04:43:17 +00002856 return posix_1str(args, "O&:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002857#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002858}
2859
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002860
Guido van Rossumb6775db1994-08-01 11:34:53 +00002861#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002862PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002863"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002864Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002865
Barry Warsaw53699e91996-12-10 23:23:01 +00002866static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002867posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002868{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002869 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002870 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002871
Barry Warsaw53699e91996-12-10 23:23:01 +00002872 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002873 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002874 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002875 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002876 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002877 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002878 u.sysname,
2879 u.nodename,
2880 u.release,
2881 u.version,
2882 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002883}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002884#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002885
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002886static int
2887extract_time(PyObject *t, long* sec, long* usec)
2888{
2889 long intval;
2890 if (PyFloat_Check(t)) {
2891 double tval = PyFloat_AsDouble(t);
Christian Heimes90aa7642007-12-19 02:45:37 +00002892 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002893 if (!intobj)
2894 return -1;
Christian Heimes217cfd12007-12-02 14:31:20 +00002895 intval = PyLong_AsLong(intobj);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002896 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002897 if (intval == -1 && PyErr_Occurred())
2898 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002899 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002900 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002901 if (*usec < 0)
2902 /* If rounding gave us a negative number,
2903 truncate. */
2904 *usec = 0;
2905 return 0;
2906 }
Christian Heimes217cfd12007-12-02 14:31:20 +00002907 intval = PyLong_AsLong(t);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002908 if (intval == -1 && PyErr_Occurred())
2909 return -1;
2910 *sec = intval;
2911 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002912 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002913}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002914
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002915PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002916"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002917utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002918Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002919second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002920
Barry Warsaw53699e91996-12-10 23:23:01 +00002921static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002922posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002923{
Thomas Wouters477c8d52006-05-27 19:21:47 +00002924#ifdef Py_WIN_WIDE_FILENAMES
2925 PyObject *arg;
2926 PyUnicodeObject *obwpath;
2927 wchar_t *wpath = NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002928 PyObject *oapath;
2929 char *apath;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002930 HANDLE hFile;
2931 long atimesec, mtimesec, ausec, musec;
2932 FILETIME atime, mtime;
2933 PyObject *result = NULL;
2934
2935 if (unicode_file_names()) {
2936 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2937 wpath = PyUnicode_AS_UNICODE(obwpath);
2938 Py_BEGIN_ALLOW_THREADS
2939 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
Thomas Wouters89f507f2006-12-13 04:49:30 +00002940 NULL, OPEN_EXISTING,
2941 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002942 Py_END_ALLOW_THREADS
2943 if (hFile == INVALID_HANDLE_VALUE)
2944 return win32_error_unicode("utime", wpath);
2945 } else
2946 /* Drop the argument parsing error as narrow strings
2947 are also valid. */
2948 PyErr_Clear();
2949 }
2950 if (!wpath) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00002951 if (!PyArg_ParseTuple(args, "O&O:utime",
2952 PyUnicode_FSConverter, &oapath, &arg))
Thomas Wouters477c8d52006-05-27 19:21:47 +00002953 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002954 apath = bytes2str(oapath, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002955 Py_BEGIN_ALLOW_THREADS
2956 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
Thomas Wouters89f507f2006-12-13 04:49:30 +00002957 NULL, OPEN_EXISTING,
2958 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002959 Py_END_ALLOW_THREADS
2960 if (hFile == INVALID_HANDLE_VALUE) {
2961 win32_error("utime", apath);
Martin v. Löwis011e8422009-05-05 04:43:17 +00002962 release_bytes(oapath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002963 return NULL;
2964 }
Martin v. Löwis011e8422009-05-05 04:43:17 +00002965 release_bytes(oapath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002966 }
2967
2968 if (arg == Py_None) {
2969 SYSTEMTIME now;
2970 GetSystemTime(&now);
2971 if (!SystemTimeToFileTime(&now, &mtime) ||
2972 !SystemTimeToFileTime(&now, &atime)) {
2973 win32_error("utime", NULL);
2974 goto done;
2975 }
2976 }
2977 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2978 PyErr_SetString(PyExc_TypeError,
2979 "utime() arg 2 must be a tuple (atime, mtime)");
2980 goto done;
2981 }
2982 else {
2983 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2984 &atimesec, &ausec) == -1)
2985 goto done;
Thomas Wouters89f507f2006-12-13 04:49:30 +00002986 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002987 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2988 &mtimesec, &musec) == -1)
2989 goto done;
Thomas Wouters89f507f2006-12-13 04:49:30 +00002990 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002991 }
2992 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2993 /* Avoid putting the file name into the error here,
2994 as that may confuse the user into believing that
2995 something is wrong with the file, when it also
2996 could be the time stamp that gives a problem. */
2997 win32_error("utime", NULL);
2998 }
2999 Py_INCREF(Py_None);
3000 result = Py_None;
3001done:
3002 CloseHandle(hFile);
3003 return result;
3004#else /* Py_WIN_WIDE_FILENAMES */
3005
Martin v. Löwis011e8422009-05-05 04:43:17 +00003006 PyObject *opath;
3007 char *path;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003008 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00003009 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00003010 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003011
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003012#if defined(HAVE_UTIMES)
3013 struct timeval buf[2];
3014#define ATIME buf[0].tv_sec
3015#define MTIME buf[1].tv_sec
3016#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00003017/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003018 struct utimbuf buf;
3019#define ATIME buf.actime
3020#define MTIME buf.modtime
3021#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003022#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003023 time_t buf[2];
3024#define ATIME buf[0]
3025#define MTIME buf[1]
3026#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003027#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003028
Mark Hammond817c9292003-12-03 01:22:38 +00003029
Martin v. Löwis011e8422009-05-05 04:43:17 +00003030 if (!PyArg_ParseTuple(args, "O&O:utime",
3031 PyUnicode_FSConverter, &opath, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003032 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003033 path = bytes2str(opath, 1);
Barry Warsaw3cef8562000-05-01 16:17:24 +00003034 if (arg == Py_None) {
3035 /* optional time values not given */
3036 Py_BEGIN_ALLOW_THREADS
3037 res = utime(path, NULL);
3038 Py_END_ALLOW_THREADS
3039 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003040 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00003041 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00003042 "utime() arg 2 must be a tuple (atime, mtime)");
Martin v. Löwis011e8422009-05-05 04:43:17 +00003043 release_bytes(opath);
Barry Warsaw3cef8562000-05-01 16:17:24 +00003044 return NULL;
3045 }
3046 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003047 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00003048 &atime, &ausec) == -1) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003049 release_bytes(opath);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003050 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00003051 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003052 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00003053 &mtime, &musec) == -1) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003054 release_bytes(opath);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003055 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00003056 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00003057 ATIME = atime;
3058 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003059#ifdef HAVE_UTIMES
3060 buf[0].tv_usec = ausec;
3061 buf[1].tv_usec = musec;
3062 Py_BEGIN_ALLOW_THREADS
3063 res = utimes(path, buf);
3064 Py_END_ALLOW_THREADS
3065#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00003066 Py_BEGIN_ALLOW_THREADS
3067 res = utime(path, UTIME_ARG);
3068 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00003069#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00003070 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00003071 if (res < 0) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003072 return posix_error_with_allocated_filename(opath);
Mark Hammond2d5914b2004-05-04 08:10:37 +00003073 }
Martin v. Löwis011e8422009-05-05 04:43:17 +00003074 release_bytes(opath);
Barry Warsaw53699e91996-12-10 23:23:01 +00003075 Py_INCREF(Py_None);
3076 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003077#undef UTIME_ARG
3078#undef ATIME
3079#undef MTIME
Thomas Wouters477c8d52006-05-27 19:21:47 +00003080#endif /* Py_WIN_WIDE_FILENAMES */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003081}
3082
Guido van Rossum85e3b011991-06-03 12:42:10 +00003083
Guido van Rossum3b066191991-06-04 19:40:25 +00003084/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003085
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003086PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003087"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003088Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003089
Barry Warsaw53699e91996-12-10 23:23:01 +00003090static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003091posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003092{
3093 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003094 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003095 return NULL;
3096 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00003097 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003098}
3099
Martin v. Löwis114619e2002-10-07 06:44:21 +00003100#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3101static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003102free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003103{
Martin v. Löwis725507b2006-03-07 12:08:51 +00003104 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00003105 for (i = 0; i < count; i++)
3106 PyMem_Free(array[i]);
3107 PyMem_DEL(array);
3108}
Martin v. Löwis011e8422009-05-05 04:43:17 +00003109
3110int fsconvert_strdup(PyObject *o, char**out)
3111{
3112 PyObject *bytes;
3113 Py_ssize_t size;
3114 if (!PyUnicode_FSConverter(o, &bytes))
3115 return 0;
3116 size = PyObject_Size(bytes);
3117 *out = PyMem_Malloc(size+1);
3118 if (!*out)
3119 return 0;
3120 /* Don't lock bytes, as we hold the GIL */
3121 memcpy(*out, bytes2str(bytes, 0), size+1);
3122 Py_DECREF(bytes);
3123 return 1;
3124}
Martin v. Löwis114619e2002-10-07 06:44:21 +00003125#endif
3126
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003127
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003128#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003129PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003130"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003131Execute an executable path with arguments, replacing current process.\n\
3132\n\
3133 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003134 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003135
Barry Warsaw53699e91996-12-10 23:23:01 +00003136static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003137posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003138{
Martin v. Löwis011e8422009-05-05 04:43:17 +00003139 PyObject *opath;
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003140 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00003141 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003142 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00003143 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003144 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003145
Guido van Rossum89b33251993-10-22 14:26:06 +00003146 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00003147 argv is a list or tuple of strings. */
3148
Martin v. Löwis011e8422009-05-05 04:43:17 +00003149 if (!PyArg_ParseTuple(args, "O&O:execv",
3150 PyUnicode_FSConverter,
3151 &opath, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003152 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003153 path = bytes2str(opath, 1);
Barry Warsaw53699e91996-12-10 23:23:01 +00003154 if (PyList_Check(argv)) {
3155 argc = PyList_Size(argv);
3156 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003157 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003158 else if (PyTuple_Check(argv)) {
3159 argc = PyTuple_Size(argv);
3160 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003161 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003162 else {
Fred Drake661ea262000-10-24 19:57:45 +00003163 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis011e8422009-05-05 04:43:17 +00003164 release_bytes(opath);
Guido van Rossum50422b42000-04-26 20:34:28 +00003165 return NULL;
3166 }
Thomas Heller6790d602007-08-30 17:15:14 +00003167 if (argc < 1) {
3168 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Martin v. Löwis011e8422009-05-05 04:43:17 +00003169 release_bytes(opath);
Thomas Heller6790d602007-08-30 17:15:14 +00003170 return NULL;
3171 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003172
Barry Warsaw53699e91996-12-10 23:23:01 +00003173 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003174 if (argvlist == NULL) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003175 release_bytes(opath);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003176 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003177 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00003178 for (i = 0; i < argc; i++) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003179 if (!fsconvert_strdup((*getitem)(argv, i),
3180 &argvlist[i])) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003181 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00003182 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00003183 "execv() arg 2 must contain only strings");
Martin v. Löwis011e8422009-05-05 04:43:17 +00003184 release_bytes(opath);
Guido van Rossum50422b42000-04-26 20:34:28 +00003185 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003186
Guido van Rossum85e3b011991-06-03 12:42:10 +00003187 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00003188 }
3189 argvlist[argc] = NULL;
3190
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003191 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003192
Guido van Rossum85e3b011991-06-03 12:42:10 +00003193 /* If we get here it's definitely an error */
3194
Martin v. Löwis114619e2002-10-07 06:44:21 +00003195 free_string_array(argvlist, argc);
Martin v. Löwis011e8422009-05-05 04:43:17 +00003196 release_bytes(opath);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003197 return posix_error();
3198}
3199
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003200
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003201PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003202"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003203Execute a path with arguments and environment, replacing current process.\n\
3204\n\
3205 path: path of executable file\n\
3206 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003207 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003208
Barry Warsaw53699e91996-12-10 23:23:01 +00003209static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003210posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003211{
Martin v. Löwis011e8422009-05-05 04:43:17 +00003212 PyObject *opath;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003213 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00003214 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003215 char **argvlist;
3216 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003217 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00003218 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003219 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00003220 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003221
3222 /* execve has three arguments: (path, argv, env), where
3223 argv is a list or tuple of strings and env is a dictionary
3224 like posix.environ. */
3225
Martin v. Löwis011e8422009-05-05 04:43:17 +00003226 if (!PyArg_ParseTuple(args, "O&OO:execve",
3227 PyUnicode_FSConverter,
3228 &opath, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003229 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003230 path = bytes2str(opath, 1);
Barry Warsaw53699e91996-12-10 23:23:01 +00003231 if (PyList_Check(argv)) {
3232 argc = PyList_Size(argv);
3233 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003234 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003235 else if (PyTuple_Check(argv)) {
3236 argc = PyTuple_Size(argv);
3237 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003238 }
3239 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003240 PyErr_SetString(PyExc_TypeError,
3241 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003242 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003243 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003244 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003245 PyErr_SetString(PyExc_TypeError,
3246 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003247 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003248 }
3249
Barry Warsaw53699e91996-12-10 23:23:01 +00003250 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003251 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003252 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003253 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003254 }
3255 for (i = 0; i < argc; i++) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003256 if (!fsconvert_strdup((*getitem)(argv, i),
3257 &argvlist[i]))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003258 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003259 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003260 goto fail_1;
3261 }
3262 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003263 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003264 argvlist[argc] = NULL;
3265
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003266 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003267 if (i < 0)
3268 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00003269 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003270 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003271 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003272 goto fail_1;
3273 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003274 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003275 keys = PyMapping_Keys(env);
3276 vals = PyMapping_Values(env);
3277 if (!keys || !vals)
3278 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003279 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3280 PyErr_SetString(PyExc_TypeError,
3281 "execve(): env.keys() or env.values() is not a list");
3282 goto fail_2;
3283 }
Tim Peters5aa91602002-01-30 05:46:57 +00003284
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003285 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003286 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003287 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003288
3289 key = PyList_GetItem(keys, pos);
3290 val = PyList_GetItem(vals, pos);
3291 if (!key || !val)
3292 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003293
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003294 if (!PyArg_Parse(
3295 key,
3296 "s;execve() arg 3 contains a non-string key",
3297 &k) ||
3298 !PyArg_Parse(
3299 val,
3300 "s;execve() arg 3 contains a non-string value",
3301 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003302 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003303 goto fail_2;
3304 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003305
3306#if defined(PYOS_OS2)
3307 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3308 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3309#endif
Christian Heimes830a4bc2007-11-22 07:43:40 +00003310 len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003311 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003312 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003313 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003314 goto fail_2;
3315 }
Tim Petersc8996f52001-12-03 20:41:00 +00003316 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003317 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003318#if defined(PYOS_OS2)
3319 }
3320#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003321 }
3322 envlist[envc] = 0;
3323
3324 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003325
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003326 /* If we get here it's definitely an error */
3327
3328 (void) posix_error();
3329
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003330 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003331 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00003332 PyMem_DEL(envlist[envc]);
3333 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003334 fail_1:
3335 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003336 Py_XDECREF(vals);
3337 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003338 fail_0:
Martin v. Löwis011e8422009-05-05 04:43:17 +00003339 release_bytes(opath);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003340 return NULL;
3341}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003342#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003343
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003344
Guido van Rossuma1065681999-01-25 23:20:23 +00003345#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003346PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003347"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003348Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003349\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003350 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003351 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003352 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003353
3354static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003355posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003356{
Martin v. Löwis011e8422009-05-05 04:43:17 +00003357 PyObject *opath;
Guido van Rossuma1065681999-01-25 23:20:23 +00003358 char *path;
3359 PyObject *argv;
3360 char **argvlist;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003361 int mode, i;
3362 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00003363 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003364 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003365
3366 /* spawnv has three arguments: (mode, path, argv), where
3367 argv is a list or tuple of strings. */
3368
Martin v. Löwis011e8422009-05-05 04:43:17 +00003369 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
3370 PyUnicode_FSConverter,
3371 &opath, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00003372 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003373 path = bytes2str(opath, 1);
Guido van Rossuma1065681999-01-25 23:20:23 +00003374 if (PyList_Check(argv)) {
3375 argc = PyList_Size(argv);
3376 getitem = PyList_GetItem;
3377 }
3378 else if (PyTuple_Check(argv)) {
3379 argc = PyTuple_Size(argv);
3380 getitem = PyTuple_GetItem;
3381 }
3382 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003383 PyErr_SetString(PyExc_TypeError,
3384 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis011e8422009-05-05 04:43:17 +00003385 release_bytes(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00003386 return NULL;
3387 }
3388
3389 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003390 if (argvlist == NULL) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003391 release_bytes(opath);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003392 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003393 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003394 for (i = 0; i < argc; i++) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003395 if (!fsconvert_strdup((*getitem)(argv, i),
3396 &argvlist[i])) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003397 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003398 PyErr_SetString(
3399 PyExc_TypeError,
3400 "spawnv() arg 2 must contain only strings");
Martin v. Löwis011e8422009-05-05 04:43:17 +00003401 release_bytes(opath);
Fred Drake137507e2000-06-01 02:02:46 +00003402 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003403 }
3404 }
3405 argvlist[argc] = NULL;
3406
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003407#if defined(PYOS_OS2) && defined(PYCC_GCC)
3408 Py_BEGIN_ALLOW_THREADS
3409 spawnval = spawnv(mode, path, argvlist);
3410 Py_END_ALLOW_THREADS
3411#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003412 if (mode == _OLD_P_OVERLAY)
3413 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003414
Tim Peters25059d32001-12-07 20:35:43 +00003415 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003416 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00003417 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003418#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003419
Martin v. Löwis114619e2002-10-07 06:44:21 +00003420 free_string_array(argvlist, argc);
Martin v. Löwis011e8422009-05-05 04:43:17 +00003421 release_bytes(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00003422
Fred Drake699f3522000-06-29 21:12:41 +00003423 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003424 return posix_error();
3425 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003426#if SIZEOF_LONG == SIZEOF_VOID_P
3427 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003428#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003429 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003430#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003431}
3432
3433
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003434PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003435"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003436Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003437\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003438 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003439 path: path of executable file\n\
3440 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003441 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003442
3443static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003444posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003445{
Martin v. Löwis011e8422009-05-05 04:43:17 +00003446 PyObject *opath;
Guido van Rossuma1065681999-01-25 23:20:23 +00003447 char *path;
3448 PyObject *argv, *env;
3449 char **argvlist;
3450 char **envlist;
3451 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003452 int mode, pos, envc;
3453 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00003454 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003455 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00003456 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003457
3458 /* spawnve has four arguments: (mode, path, argv, env), where
3459 argv is a list or tuple of strings and env is a dictionary
3460 like posix.environ. */
3461
Martin v. Löwis011e8422009-05-05 04:43:17 +00003462 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
3463 PyUnicode_FSConverter,
3464 &opath, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00003465 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003466 path = bytes2str(opath, 1);
Guido van Rossuma1065681999-01-25 23:20:23 +00003467 if (PyList_Check(argv)) {
3468 argc = PyList_Size(argv);
3469 getitem = PyList_GetItem;
3470 }
3471 else if (PyTuple_Check(argv)) {
3472 argc = PyTuple_Size(argv);
3473 getitem = PyTuple_GetItem;
3474 }
3475 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003476 PyErr_SetString(PyExc_TypeError,
3477 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003478 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003479 }
3480 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003481 PyErr_SetString(PyExc_TypeError,
3482 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003483 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003484 }
3485
3486 argvlist = PyMem_NEW(char *, argc+1);
3487 if (argvlist == NULL) {
3488 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003489 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003490 }
3491 for (i = 0; i < argc; i++) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003492 if (!fsconvert_strdup((*getitem)(argv, i),
3493 &argvlist[i]))
Guido van Rossuma1065681999-01-25 23:20:23 +00003494 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003495 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00003496 goto fail_1;
3497 }
3498 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003499 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00003500 argvlist[argc] = NULL;
3501
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003502 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003503 if (i < 0)
3504 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003505 envlist = PyMem_NEW(char *, i + 1);
3506 if (envlist == NULL) {
3507 PyErr_NoMemory();
3508 goto fail_1;
3509 }
3510 envc = 0;
3511 keys = PyMapping_Keys(env);
3512 vals = PyMapping_Values(env);
3513 if (!keys || !vals)
3514 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003515 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3516 PyErr_SetString(PyExc_TypeError,
3517 "spawnve(): env.keys() or env.values() is not a list");
3518 goto fail_2;
3519 }
Tim Peters5aa91602002-01-30 05:46:57 +00003520
Guido van Rossuma1065681999-01-25 23:20:23 +00003521 for (pos = 0; pos < i; pos++) {
3522 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003523 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003524
3525 key = PyList_GetItem(keys, pos);
3526 val = PyList_GetItem(vals, pos);
3527 if (!key || !val)
3528 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003529
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003530 if (!PyArg_Parse(
3531 key,
3532 "s;spawnve() arg 3 contains a non-string key",
3533 &k) ||
3534 !PyArg_Parse(
3535 val,
3536 "s;spawnve() arg 3 contains a non-string value",
3537 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00003538 {
3539 goto fail_2;
3540 }
Christian Heimes830a4bc2007-11-22 07:43:40 +00003541 len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003542 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003543 if (p == NULL) {
3544 PyErr_NoMemory();
3545 goto fail_2;
3546 }
Tim Petersc8996f52001-12-03 20:41:00 +00003547 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003548 envlist[envc++] = p;
3549 }
3550 envlist[envc] = 0;
3551
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003552#if defined(PYOS_OS2) && defined(PYCC_GCC)
3553 Py_BEGIN_ALLOW_THREADS
3554 spawnval = spawnve(mode, path, argvlist, envlist);
3555 Py_END_ALLOW_THREADS
3556#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003557 if (mode == _OLD_P_OVERLAY)
3558 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003559
3560 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003561 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003562 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003563#endif
Tim Peters25059d32001-12-07 20:35:43 +00003564
Fred Drake699f3522000-06-29 21:12:41 +00003565 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003566 (void) posix_error();
3567 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003568#if SIZEOF_LONG == SIZEOF_VOID_P
3569 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003570#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003571 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003572#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003573
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003574 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003575 while (--envc >= 0)
3576 PyMem_DEL(envlist[envc]);
3577 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003578 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003579 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003580 Py_XDECREF(vals);
3581 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003582 fail_0:
Martin v. Löwis011e8422009-05-05 04:43:17 +00003583 release_bytes(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00003584 return res;
3585}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003586
3587/* OS/2 supports spawnvp & spawnvpe natively */
3588#if defined(PYOS_OS2)
3589PyDoc_STRVAR(posix_spawnvp__doc__,
3590"spawnvp(mode, file, args)\n\n\
3591Execute the program 'file' in a new process, using the environment\n\
3592search path to find the file.\n\
3593\n\
3594 mode: mode of process creation\n\
3595 file: executable file name\n\
3596 args: tuple or list of strings");
3597
3598static PyObject *
3599posix_spawnvp(PyObject *self, PyObject *args)
3600{
Martin v. Löwis011e8422009-05-05 04:43:17 +00003601 PyObject *opath;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003602 char *path;
3603 PyObject *argv;
3604 char **argvlist;
3605 int mode, i, argc;
3606 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003607 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003608
3609 /* spawnvp has three arguments: (mode, path, argv), where
3610 argv is a list or tuple of strings. */
3611
Martin v. Löwis011e8422009-05-05 04:43:17 +00003612 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
3613 PyUnicode_FSConverter,
3614 &opath, &argv))
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003615 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003616 path = bytes2str(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003617 if (PyList_Check(argv)) {
3618 argc = PyList_Size(argv);
3619 getitem = PyList_GetItem;
3620 }
3621 else if (PyTuple_Check(argv)) {
3622 argc = PyTuple_Size(argv);
3623 getitem = PyTuple_GetItem;
3624 }
3625 else {
3626 PyErr_SetString(PyExc_TypeError,
3627 "spawnvp() arg 2 must be a tuple or list");
Martin v. Löwis011e8422009-05-05 04:43:17 +00003628 release_bytes(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003629 return NULL;
3630 }
3631
3632 argvlist = PyMem_NEW(char *, argc+1);
3633 if (argvlist == NULL) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003634 release_bytes(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003635 return PyErr_NoMemory();
3636 }
3637 for (i = 0; i < argc; i++) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003638 if (!fsconvert_strdup((*getitem)(argv, i),
3639 &argvlist[i])) {
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003640 free_string_array(argvlist, i);
3641 PyErr_SetString(
3642 PyExc_TypeError,
3643 "spawnvp() arg 2 must contain only strings");
Martin v. Löwis011e8422009-05-05 04:43:17 +00003644 release_bytes(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003645 return NULL;
3646 }
3647 }
3648 argvlist[argc] = NULL;
3649
3650 Py_BEGIN_ALLOW_THREADS
3651#if defined(PYCC_GCC)
3652 spawnval = spawnvp(mode, path, argvlist);
3653#else
3654 spawnval = _spawnvp(mode, path, argvlist);
3655#endif
3656 Py_END_ALLOW_THREADS
3657
3658 free_string_array(argvlist, argc);
Martin v. Löwis011e8422009-05-05 04:43:17 +00003659 release_bytes(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003660
3661 if (spawnval == -1)
3662 return posix_error();
3663 else
3664 return Py_BuildValue("l", (long) spawnval);
3665}
3666
3667
3668PyDoc_STRVAR(posix_spawnvpe__doc__,
3669"spawnvpe(mode, file, args, env)\n\n\
3670Execute the program 'file' in a new process, using the environment\n\
3671search path to find the file.\n\
3672\n\
3673 mode: mode of process creation\n\
3674 file: executable file name\n\
3675 args: tuple or list of arguments\n\
3676 env: dictionary of strings mapping to strings");
3677
3678static PyObject *
3679posix_spawnvpe(PyObject *self, PyObject *args)
3680{
Martin v. Löwis011e8422009-05-05 04:43:17 +00003681 PyObject *opath
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003682 char *path;
3683 PyObject *argv, *env;
3684 char **argvlist;
3685 char **envlist;
3686 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3687 int mode, i, pos, argc, envc;
3688 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003689 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003690 int lastarg = 0;
3691
3692 /* spawnvpe has four arguments: (mode, path, argv, env), where
3693 argv is a list or tuple of strings and env is a dictionary
3694 like posix.environ. */
3695
3696 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
Martin v. Löwis011e8422009-05-05 04:43:17 +00003697 PyUnicode_FSConverter,
3698 &opath, &argv, &env))
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003699 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003700 path = bytes2str(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003701 if (PyList_Check(argv)) {
3702 argc = PyList_Size(argv);
3703 getitem = PyList_GetItem;
3704 }
3705 else if (PyTuple_Check(argv)) {
3706 argc = PyTuple_Size(argv);
3707 getitem = PyTuple_GetItem;
3708 }
3709 else {
3710 PyErr_SetString(PyExc_TypeError,
3711 "spawnvpe() arg 2 must be a tuple or list");
3712 goto fail_0;
3713 }
3714 if (!PyMapping_Check(env)) {
3715 PyErr_SetString(PyExc_TypeError,
3716 "spawnvpe() arg 3 must be a mapping object");
3717 goto fail_0;
3718 }
3719
3720 argvlist = PyMem_NEW(char *, argc+1);
3721 if (argvlist == NULL) {
3722 PyErr_NoMemory();
3723 goto fail_0;
3724 }
3725 for (i = 0; i < argc; i++) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003726 if (!fsconvert_strdup((*getitem)(argv, i),
3727 &argvlist[i]))
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003728 {
3729 lastarg = i;
3730 goto fail_1;
3731 }
3732 }
3733 lastarg = argc;
3734 argvlist[argc] = NULL;
3735
3736 i = PyMapping_Size(env);
3737 if (i < 0)
3738 goto fail_1;
3739 envlist = PyMem_NEW(char *, i + 1);
3740 if (envlist == NULL) {
3741 PyErr_NoMemory();
3742 goto fail_1;
3743 }
3744 envc = 0;
3745 keys = PyMapping_Keys(env);
3746 vals = PyMapping_Values(env);
3747 if (!keys || !vals)
3748 goto fail_2;
3749 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3750 PyErr_SetString(PyExc_TypeError,
3751 "spawnvpe(): env.keys() or env.values() is not a list");
3752 goto fail_2;
3753 }
3754
3755 for (pos = 0; pos < i; pos++) {
3756 char *p, *k, *v;
3757 size_t len;
3758
3759 key = PyList_GetItem(keys, pos);
3760 val = PyList_GetItem(vals, pos);
3761 if (!key || !val)
3762 goto fail_2;
3763
3764 if (!PyArg_Parse(
3765 key,
3766 "s;spawnvpe() arg 3 contains a non-string key",
3767 &k) ||
3768 !PyArg_Parse(
3769 val,
3770 "s;spawnvpe() arg 3 contains a non-string value",
3771 &v))
3772 {
3773 goto fail_2;
3774 }
Christian Heimes830a4bc2007-11-22 07:43:40 +00003775 len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003776 p = PyMem_NEW(char, len);
3777 if (p == NULL) {
3778 PyErr_NoMemory();
3779 goto fail_2;
3780 }
3781 PyOS_snprintf(p, len, "%s=%s", k, v);
3782 envlist[envc++] = p;
3783 }
3784 envlist[envc] = 0;
3785
3786 Py_BEGIN_ALLOW_THREADS
3787#if defined(PYCC_GCC)
Christian Heimes292d3512008-02-03 16:51:08 +00003788 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003789#else
Christian Heimes292d3512008-02-03 16:51:08 +00003790 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003791#endif
3792 Py_END_ALLOW_THREADS
3793
3794 if (spawnval == -1)
3795 (void) posix_error();
3796 else
3797 res = Py_BuildValue("l", (long) spawnval);
3798
3799 fail_2:
3800 while (--envc >= 0)
3801 PyMem_DEL(envlist[envc]);
3802 PyMem_DEL(envlist);
3803 fail_1:
3804 free_string_array(argvlist, lastarg);
3805 Py_XDECREF(vals);
3806 Py_XDECREF(keys);
3807 fail_0:
Martin v. Löwis011e8422009-05-05 04:43:17 +00003808 release_bytes(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003809 return res;
3810}
3811#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003812#endif /* HAVE_SPAWNV */
3813
3814
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003815#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003816PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003817"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003818Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3819\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003820Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003821
3822static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003823posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003824{
Christian Heimes400adb02008-02-01 08:12:03 +00003825 pid_t pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003826 if (pid == -1)
3827 return posix_error();
Georg Brandl2ee470f2008-07-16 12:55:28 +00003828 if (pid == 0)
3829 PyOS_AfterFork();
Christian Heimes400adb02008-02-01 08:12:03 +00003830 return PyLong_FromLong(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003831}
3832#endif
3833
3834
Guido van Rossumad0ee831995-03-01 10:34:45 +00003835#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003836PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003837"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003838Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003839Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003840
Barry Warsaw53699e91996-12-10 23:23:01 +00003841static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003842posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003843{
Christian Heimes400adb02008-02-01 08:12:03 +00003844 pid_t pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003845 if (pid == -1)
3846 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003847 if (pid == 0)
3848 PyOS_AfterFork();
Christian Heimes400adb02008-02-01 08:12:03 +00003849 return PyLong_FromLong(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003850}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003851#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003852
Neal Norwitzb59798b2003-03-21 01:43:31 +00003853/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003854/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3855#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003856#define DEV_PTY_FILE "/dev/ptc"
3857#define HAVE_DEV_PTMX
3858#else
3859#define DEV_PTY_FILE "/dev/ptmx"
3860#endif
3861
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003862#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003863#ifdef HAVE_PTY_H
3864#include <pty.h>
3865#else
3866#ifdef HAVE_LIBUTIL_H
3867#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003868#endif /* HAVE_LIBUTIL_H */
3869#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003870#ifdef HAVE_STROPTS_H
3871#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003872#endif
3873#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003874
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003875#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003876PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003877"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003878Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003879
3880static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003881posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003882{
3883 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003884#ifndef HAVE_OPENPTY
3885 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003886#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003887#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003888 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003889#ifdef sun
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003890 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003891#endif
3892#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003893
Thomas Wouters70c21a12000-07-14 14:28:33 +00003894#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003895 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3896 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003897#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003898 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3899 if (slave_name == NULL)
3900 return posix_error();
3901
3902 slave_fd = open(slave_name, O_RDWR);
3903 if (slave_fd < 0)
3904 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003905#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003906 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003907 if (master_fd < 0)
3908 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003909 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003910 /* change permission of slave */
3911 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003912 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003913 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003914 }
3915 /* unlock slave */
3916 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003917 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003918 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003919 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003920 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003921 slave_name = ptsname(master_fd); /* get name of slave */
3922 if (slave_name == NULL)
3923 return posix_error();
3924 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3925 if (slave_fd < 0)
3926 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003927#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003928 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3929 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003930#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003931 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003932#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003933#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003934#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003935
Fred Drake8cef4cf2000-06-28 16:40:38 +00003936 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003937
Fred Drake8cef4cf2000-06-28 16:40:38 +00003938}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003939#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003940
3941#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003942PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003943"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003944Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3945Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003946To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003947
3948static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003949posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003950{
Christian Heimes400adb02008-02-01 08:12:03 +00003951 int master_fd = -1;
3952 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003953
Fred Drake8cef4cf2000-06-28 16:40:38 +00003954 pid = forkpty(&master_fd, NULL, NULL, NULL);
3955 if (pid == -1)
3956 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003957 if (pid == 0)
3958 PyOS_AfterFork();
Christian Heimes400adb02008-02-01 08:12:03 +00003959 return Py_BuildValue("(li)", pid, master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00003960}
3961#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003962
Guido van Rossumad0ee831995-03-01 10:34:45 +00003963#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003964PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003965"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003966Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003967
Barry Warsaw53699e91996-12-10 23:23:01 +00003968static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003969posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003970{
Christian Heimes217cfd12007-12-02 14:31:20 +00003971 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003972}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003973#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003974
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003975
Guido van Rossumad0ee831995-03-01 10:34:45 +00003976#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003977PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003978"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003979Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003980
Barry Warsaw53699e91996-12-10 23:23:01 +00003981static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003982posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003983{
Christian Heimes217cfd12007-12-02 14:31:20 +00003984 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003985}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003986#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003987
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003988
Guido van Rossumad0ee831995-03-01 10:34:45 +00003989#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003990PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003991"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003992Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003993
Barry Warsaw53699e91996-12-10 23:23:01 +00003994static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003995posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003996{
Christian Heimes217cfd12007-12-02 14:31:20 +00003997 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003998}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003999#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004000
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004001
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004002PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004003"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004004Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004005
Barry Warsaw53699e91996-12-10 23:23:01 +00004006static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004007posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004008{
Christian Heimes217cfd12007-12-02 14:31:20 +00004009 return PyLong_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004010}
4011
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004012
Fred Drakec9680921999-12-13 16:37:25 +00004013#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004014PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004015"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004016Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00004017
4018static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004019posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00004020{
4021 PyObject *result = NULL;
4022
Fred Drakec9680921999-12-13 16:37:25 +00004023#ifdef NGROUPS_MAX
4024#define MAX_GROUPS NGROUPS_MAX
4025#else
4026 /* defined to be 16 on Solaris7, so this should be a small number */
4027#define MAX_GROUPS 64
4028#endif
4029 gid_t grouplist[MAX_GROUPS];
4030 int n;
4031
4032 n = getgroups(MAX_GROUPS, grouplist);
4033 if (n < 0)
4034 posix_error();
4035 else {
4036 result = PyList_New(n);
4037 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00004038 int i;
4039 for (i = 0; i < n; ++i) {
Christian Heimes217cfd12007-12-02 14:31:20 +00004040 PyObject *o = PyLong_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00004041 if (o == NULL) {
4042 Py_DECREF(result);
4043 result = NULL;
4044 break;
4045 }
4046 PyList_SET_ITEM(result, i, o);
4047 }
4048 }
4049 }
Neal Norwitze241ce82003-02-17 18:17:05 +00004050
Fred Drakec9680921999-12-13 16:37:25 +00004051 return result;
4052}
4053#endif
4054
Martin v. Löwis606edc12002-06-13 21:09:11 +00004055#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004056PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004057"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004058Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00004059
4060static PyObject *
4061posix_getpgid(PyObject *self, PyObject *args)
4062{
4063 int pid, pgid;
4064 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
4065 return NULL;
4066 pgid = getpgid(pid);
4067 if (pgid < 0)
4068 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00004069 return PyLong_FromLong((long)pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004070}
4071#endif /* HAVE_GETPGID */
4072
4073
Guido van Rossumb6775db1994-08-01 11:34:53 +00004074#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004075PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004076"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004077Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004078
Barry Warsaw53699e91996-12-10 23:23:01 +00004079static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004080posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004081{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004082#ifdef GETPGRP_HAVE_ARG
Christian Heimes217cfd12007-12-02 14:31:20 +00004083 return PyLong_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004084#else /* GETPGRP_HAVE_ARG */
Christian Heimes217cfd12007-12-02 14:31:20 +00004085 return PyLong_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004086#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004087}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004088#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004089
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004090
Guido van Rossumb6775db1994-08-01 11:34:53 +00004091#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004092PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004093"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004094Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004095
Barry Warsaw53699e91996-12-10 23:23:01 +00004096static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004097posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004098{
Guido van Rossum64933891994-10-20 21:56:42 +00004099#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00004100 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004101#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004102 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004103#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00004104 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004105 Py_INCREF(Py_None);
4106 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004107}
4108
Guido van Rossumb6775db1994-08-01 11:34:53 +00004109#endif /* HAVE_SETPGRP */
4110
Guido van Rossumad0ee831995-03-01 10:34:45 +00004111#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004112PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004113"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004114Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004115
Barry Warsaw53699e91996-12-10 23:23:01 +00004116static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004117posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004118{
Christian Heimes217cfd12007-12-02 14:31:20 +00004119 return PyLong_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004120}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004121#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004122
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004123
Fred Drake12c6e2d1999-12-14 21:25:03 +00004124#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004125PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004126"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004127Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004128
4129static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004130posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004131{
Neal Norwitze241ce82003-02-17 18:17:05 +00004132 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00004133 char *name;
4134 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004135
Fred Drakea30680b2000-12-06 21:24:28 +00004136 errno = 0;
4137 name = getlogin();
4138 if (name == NULL) {
4139 if (errno)
4140 posix_error();
4141 else
4142 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00004143 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00004144 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00004145 else
Neal Norwitz93c56822007-08-26 07:10:06 +00004146 result = PyUnicode_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00004147 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004148
Fred Drake12c6e2d1999-12-14 21:25:03 +00004149 return result;
4150}
4151#endif
4152
Guido van Rossumad0ee831995-03-01 10:34:45 +00004153#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004154PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004155"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004156Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004157
Barry Warsaw53699e91996-12-10 23:23:01 +00004158static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004159posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004160{
Christian Heimes217cfd12007-12-02 14:31:20 +00004161 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004162}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004163#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004164
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004165
Guido van Rossumad0ee831995-03-01 10:34:45 +00004166#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004167PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004168"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004169Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004170
Barry Warsaw53699e91996-12-10 23:23:01 +00004171static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004172posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004173{
Christian Heimes292d3512008-02-03 16:51:08 +00004174 pid_t pid;
4175 int sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004176 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00004177 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004178#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004179 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4180 APIRET rc;
4181 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004182 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004183
4184 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4185 APIRET rc;
4186 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004187 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004188
4189 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004190 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004191#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00004192 if (kill(pid, sig) == -1)
4193 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004194#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004195 Py_INCREF(Py_None);
4196 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004197}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004198#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004199
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004200#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004201PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004202"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004203Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004204
4205static PyObject *
4206posix_killpg(PyObject *self, PyObject *args)
4207{
4208 int pgid, sig;
4209 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
4210 return NULL;
4211 if (killpg(pgid, sig) == -1)
4212 return posix_error();
4213 Py_INCREF(Py_None);
4214 return Py_None;
4215}
4216#endif
4217
Guido van Rossumc0125471996-06-28 18:55:32 +00004218#ifdef HAVE_PLOCK
4219
4220#ifdef HAVE_SYS_LOCK_H
4221#include <sys/lock.h>
4222#endif
4223
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004224PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004225"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004226Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004227
Barry Warsaw53699e91996-12-10 23:23:01 +00004228static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004229posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004230{
4231 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004232 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00004233 return NULL;
4234 if (plock(op) == -1)
4235 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004236 Py_INCREF(Py_None);
4237 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004238}
4239#endif
4240
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004241
Guido van Rossum3b066191991-06-04 19:40:25 +00004242
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004243
Guido van Rossumb6775db1994-08-01 11:34:53 +00004244#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004245PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004246"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004247Set the current process's user id.");
4248
Barry Warsaw53699e91996-12-10 23:23:01 +00004249static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004250posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004251{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004252 long uid_arg;
4253 uid_t uid;
4254 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004255 return NULL;
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004256 uid = uid_arg;
4257 if (uid != uid_arg) {
4258 PyErr_SetString(PyExc_OverflowError, "user id too big");
4259 return NULL;
4260 }
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004261 if (setuid(uid) < 0)
4262 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004263 Py_INCREF(Py_None);
4264 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004265}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004266#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004267
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004268
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004269#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004270PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004271"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004272Set the current process's effective user id.");
4273
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004274static PyObject *
4275posix_seteuid (PyObject *self, PyObject *args)
4276{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004277 long euid_arg;
4278 uid_t euid;
4279 if (!PyArg_ParseTuple(args, "l", &euid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004280 return NULL;
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004281 euid = euid_arg;
4282 if (euid != euid_arg) {
4283 PyErr_SetString(PyExc_OverflowError, "user id too big");
4284 return NULL;
4285 }
4286 if (seteuid(euid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004287 return posix_error();
4288 } else {
4289 Py_INCREF(Py_None);
4290 return Py_None;
4291 }
4292}
4293#endif /* HAVE_SETEUID */
4294
4295#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004296PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004297"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004298Set the current process's effective group id.");
4299
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004300static PyObject *
4301posix_setegid (PyObject *self, PyObject *args)
4302{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004303 long egid_arg;
4304 gid_t egid;
4305 if (!PyArg_ParseTuple(args, "l", &egid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004306 return NULL;
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004307 egid = egid_arg;
4308 if (egid != egid_arg) {
4309 PyErr_SetString(PyExc_OverflowError, "group id too big");
4310 return NULL;
4311 }
4312 if (setegid(egid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004313 return posix_error();
4314 } else {
4315 Py_INCREF(Py_None);
4316 return Py_None;
4317 }
4318}
4319#endif /* HAVE_SETEGID */
4320
4321#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004322PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004323"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004324Set the current process's real and effective user ids.");
4325
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004326static PyObject *
4327posix_setreuid (PyObject *self, PyObject *args)
4328{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004329 long ruid_arg, euid_arg;
4330 uid_t ruid, euid;
4331 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004332 return NULL;
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004333 ruid = ruid_arg;
4334 euid = euid_arg;
4335 if (euid != euid_arg || ruid != ruid_arg) {
4336 PyErr_SetString(PyExc_OverflowError, "user id too big");
4337 return NULL;
4338 }
4339 if (setreuid(ruid, euid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004340 return posix_error();
4341 } else {
4342 Py_INCREF(Py_None);
4343 return Py_None;
4344 }
4345}
4346#endif /* HAVE_SETREUID */
4347
4348#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004349PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004350"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004351Set the current process's real and effective group ids.");
4352
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004353static PyObject *
4354posix_setregid (PyObject *self, PyObject *args)
4355{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004356 long rgid_arg, egid_arg;
4357 gid_t rgid, egid;
4358 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004359 return NULL;
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004360 rgid = rgid_arg;
4361 egid = egid_arg;
4362 if (egid != egid_arg || rgid != rgid_arg) {
4363 PyErr_SetString(PyExc_OverflowError, "group id too big");
4364 return NULL;
4365 }
4366 if (setregid(rgid, egid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004367 return posix_error();
4368 } else {
4369 Py_INCREF(Py_None);
4370 return Py_None;
4371 }
4372}
4373#endif /* HAVE_SETREGID */
4374
Guido van Rossumb6775db1994-08-01 11:34:53 +00004375#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004376PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004377"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004378Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004379
Barry Warsaw53699e91996-12-10 23:23:01 +00004380static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004381posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004382{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004383 long gid_arg;
4384 gid_t gid;
4385 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004386 return NULL;
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004387 gid = gid_arg;
4388 if (gid != gid_arg) {
4389 PyErr_SetString(PyExc_OverflowError, "group id too big");
4390 return NULL;
4391 }
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004392 if (setgid(gid) < 0)
4393 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004394 Py_INCREF(Py_None);
4395 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004396}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004397#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004398
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004399#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004400PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004401"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004402Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004403
4404static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004405posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004406{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004407 int i, len;
4408 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004409
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004410 if (!PySequence_Check(groups)) {
4411 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4412 return NULL;
4413 }
4414 len = PySequence_Size(groups);
4415 if (len > MAX_GROUPS) {
4416 PyErr_SetString(PyExc_ValueError, "too many groups");
4417 return NULL;
4418 }
4419 for(i = 0; i < len; i++) {
4420 PyObject *elem;
4421 elem = PySequence_GetItem(groups, i);
4422 if (!elem)
4423 return NULL;
Guido van Rossumddefaf32007-01-14 03:31:43 +00004424 if (!PyLong_Check(elem)) {
4425 PyErr_SetString(PyExc_TypeError,
4426 "groups must be integers");
4427 Py_DECREF(elem);
4428 return NULL;
4429 } else {
4430 unsigned long x = PyLong_AsUnsignedLong(elem);
4431 if (PyErr_Occurred()) {
4432 PyErr_SetString(PyExc_TypeError,
4433 "group id too big");
Georg Brandla13c2442005-11-22 19:30:31 +00004434 Py_DECREF(elem);
4435 return NULL;
Georg Brandla13c2442005-11-22 19:30:31 +00004436 }
Georg Brandla13c2442005-11-22 19:30:31 +00004437 grouplist[i] = x;
Guido van Rossumddefaf32007-01-14 03:31:43 +00004438 /* read back the value to see if it fitted in gid_t */
Georg Brandla13c2442005-11-22 19:30:31 +00004439 if (grouplist[i] != x) {
4440 PyErr_SetString(PyExc_TypeError,
4441 "group id too big");
4442 Py_DECREF(elem);
4443 return NULL;
4444 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004445 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004446 Py_DECREF(elem);
4447 }
4448
4449 if (setgroups(len, grouplist) < 0)
4450 return posix_error();
4451 Py_INCREF(Py_None);
4452 return Py_None;
4453}
4454#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004455
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004456#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4457static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00004458wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004459{
4460 PyObject *result;
4461 static PyObject *struct_rusage;
4462
4463 if (pid == -1)
4464 return posix_error();
4465
4466 if (struct_rusage == NULL) {
Christian Heimes072c0f12008-01-03 23:01:04 +00004467 PyObject *m = PyImport_ImportModuleNoBlock("resource");
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004468 if (m == NULL)
4469 return NULL;
4470 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4471 Py_DECREF(m);
4472 if (struct_rusage == NULL)
4473 return NULL;
4474 }
4475
4476 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4477 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4478 if (!result)
4479 return NULL;
4480
4481#ifndef doubletime
4482#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4483#endif
4484
4485 PyStructSequence_SET_ITEM(result, 0,
4486 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4487 PyStructSequence_SET_ITEM(result, 1,
4488 PyFloat_FromDouble(doubletime(ru->ru_stime)));
4489#define SET_INT(result, index, value)\
Christian Heimes217cfd12007-12-02 14:31:20 +00004490 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004491 SET_INT(result, 2, ru->ru_maxrss);
4492 SET_INT(result, 3, ru->ru_ixrss);
4493 SET_INT(result, 4, ru->ru_idrss);
4494 SET_INT(result, 5, ru->ru_isrss);
4495 SET_INT(result, 6, ru->ru_minflt);
4496 SET_INT(result, 7, ru->ru_majflt);
4497 SET_INT(result, 8, ru->ru_nswap);
4498 SET_INT(result, 9, ru->ru_inblock);
4499 SET_INT(result, 10, ru->ru_oublock);
4500 SET_INT(result, 11, ru->ru_msgsnd);
4501 SET_INT(result, 12, ru->ru_msgrcv);
4502 SET_INT(result, 13, ru->ru_nsignals);
4503 SET_INT(result, 14, ru->ru_nvcsw);
4504 SET_INT(result, 15, ru->ru_nivcsw);
4505#undef SET_INT
4506
4507 if (PyErr_Occurred()) {
4508 Py_DECREF(result);
4509 return NULL;
4510 }
4511
4512 return Py_BuildValue("iiN", pid, status, result);
4513}
4514#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4515
4516#ifdef HAVE_WAIT3
4517PyDoc_STRVAR(posix_wait3__doc__,
4518"wait3(options) -> (pid, status, rusage)\n\n\
4519Wait for completion of a child process.");
4520
4521static PyObject *
4522posix_wait3(PyObject *self, PyObject *args)
4523{
Christian Heimes292d3512008-02-03 16:51:08 +00004524 pid_t pid;
4525 int options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004526 struct rusage ru;
4527 WAIT_TYPE status;
4528 WAIT_STATUS_INT(status) = 0;
4529
4530 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4531 return NULL;
4532
4533 Py_BEGIN_ALLOW_THREADS
4534 pid = wait3(&status, options, &ru);
4535 Py_END_ALLOW_THREADS
4536
4537 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
4538}
4539#endif /* HAVE_WAIT3 */
4540
4541#ifdef HAVE_WAIT4
4542PyDoc_STRVAR(posix_wait4__doc__,
4543"wait4(pid, options) -> (pid, status, rusage)\n\n\
4544Wait for completion of a given child process.");
4545
4546static PyObject *
4547posix_wait4(PyObject *self, PyObject *args)
4548{
Christian Heimes292d3512008-02-03 16:51:08 +00004549 pid_t pid;
4550 int options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004551 struct rusage ru;
4552 WAIT_TYPE status;
4553 WAIT_STATUS_INT(status) = 0;
4554
4555 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
4556 return NULL;
4557
4558 Py_BEGIN_ALLOW_THREADS
4559 pid = wait4(pid, &status, options, &ru);
4560 Py_END_ALLOW_THREADS
4561
4562 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
4563}
4564#endif /* HAVE_WAIT4 */
4565
Guido van Rossumb6775db1994-08-01 11:34:53 +00004566#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004567PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004568"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004569Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004570
Barry Warsaw53699e91996-12-10 23:23:01 +00004571static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004572posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004573{
Christian Heimes292d3512008-02-03 16:51:08 +00004574 pid_t pid;
4575 int options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004576 WAIT_TYPE status;
4577 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004578
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004579 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004580 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004581 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004582 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004583 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004584 if (pid == -1)
4585 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004586
4587 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00004588}
4589
Tim Petersab034fa2002-02-01 11:27:43 +00004590#elif defined(HAVE_CWAIT)
4591
4592/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004593PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004594"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004595"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004596
4597static PyObject *
4598posix_waitpid(PyObject *self, PyObject *args)
4599{
Thomas Wouters477c8d52006-05-27 19:21:47 +00004600 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004601 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00004602
4603 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4604 return NULL;
4605 Py_BEGIN_ALLOW_THREADS
4606 pid = _cwait(&status, pid, options);
4607 Py_END_ALLOW_THREADS
4608 if (pid == -1)
4609 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004610
4611 /* shift the status left a byte so this is more like the POSIX waitpid */
4612 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00004613}
4614#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004615
Guido van Rossumad0ee831995-03-01 10:34:45 +00004616#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004617PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004618"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004619Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004620
Barry Warsaw53699e91996-12-10 23:23:01 +00004621static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004622posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004623{
Christian Heimes292d3512008-02-03 16:51:08 +00004624 pid_t pid;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004625 WAIT_TYPE status;
4626 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00004627
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004628 Py_BEGIN_ALLOW_THREADS
4629 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004630 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004631 if (pid == -1)
4632 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004633
4634 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00004635}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004636#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004637
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004638
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004639PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004640"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004641Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004642
Barry Warsaw53699e91996-12-10 23:23:01 +00004643static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004644posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004645{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004646#ifdef HAVE_LSTAT
Martin v. Löwis011e8422009-05-05 04:43:17 +00004647 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004648#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004649#ifdef MS_WINDOWS
Martin v. Löwis011e8422009-05-05 04:43:17 +00004650 return posix_do_stat(self, args, "O&:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004651#else
Martin v. Löwis011e8422009-05-05 04:43:17 +00004652 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004653#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004654#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004655}
4656
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004657
Guido van Rossumb6775db1994-08-01 11:34:53 +00004658#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004659PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004660"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004661Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004662
Barry Warsaw53699e91996-12-10 23:23:01 +00004663static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004664posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004665{
Thomas Wouters89f507f2006-12-13 04:49:30 +00004666 PyObject* v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00004667 char buf[MAXPATHLEN];
Martin v. Löwis011e8422009-05-05 04:43:17 +00004668 PyObject *opath;
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004669 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004670 int n;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004671 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004672
Martin v. Löwis011e8422009-05-05 04:43:17 +00004673 if (!PyArg_ParseTuple(args, "O&:readlink",
4674 PyUnicode_FSConverter, &opath))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004675 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004676 path = bytes2str(opath, 1);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004677 v = PySequence_GetItem(args, 0);
Neal Norwitzcda5c062007-08-12 17:09:36 +00004678 if (v == NULL) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00004679 release_bytes(opath);
Neal Norwitzcda5c062007-08-12 17:09:36 +00004680 return NULL;
4681 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00004682
4683 if (PyUnicode_Check(v)) {
4684 arg_is_unicode = 1;
4685 }
4686 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004687
Barry Warsaw53699e91996-12-10 23:23:01 +00004688 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004689 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004690 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004691 if (n < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004692 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004693
Martin v. Löwis011e8422009-05-05 04:43:17 +00004694 release_bytes(opath);
Christian Heimes72b710a2008-05-26 13:28:38 +00004695 v = PyBytes_FromStringAndSize(buf, n);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004696 if (arg_is_unicode) {
4697 PyObject *w;
4698
4699 w = PyUnicode_FromEncodedObject(v,
4700 Py_FileSystemDefaultEncoding,
Martin v. Löwis43c57782009-05-10 08:15:24 +00004701 "surrogateescape");
Thomas Wouters89f507f2006-12-13 04:49:30 +00004702 if (w != NULL) {
4703 Py_DECREF(v);
4704 v = w;
4705 }
4706 else {
Guido van Rossumf0af3e32008-10-02 18:55:37 +00004707 v = NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004708 }
4709 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00004710 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004711}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004712#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004713
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004714
Guido van Rossumb6775db1994-08-01 11:34:53 +00004715#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004716PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004717"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00004718Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004719
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004720static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004721posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004722{
Martin v. Löwis011e8422009-05-05 04:43:17 +00004723 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004724}
4725#endif /* HAVE_SYMLINK */
4726
4727
4728#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00004729#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4730static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004731system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004732{
4733 ULONG value = 0;
4734
4735 Py_BEGIN_ALLOW_THREADS
4736 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4737 Py_END_ALLOW_THREADS
4738
4739 return value;
4740}
4741
4742static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004743posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004744{
Guido van Rossumd48f2521997-12-05 22:19:34 +00004745 /* Currently Only Uptime is Provided -- Others Later */
4746 return Py_BuildValue("ddddd",
4747 (double)0 /* t.tms_utime / HZ */,
4748 (double)0 /* t.tms_stime / HZ */,
4749 (double)0 /* t.tms_cutime / HZ */,
4750 (double)0 /* t.tms_cstime / HZ */,
4751 (double)system_uptime() / 1000);
4752}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004753#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00004754#define NEED_TICKS_PER_SECOND
4755static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00004756static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004757posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004758{
4759 struct tms t;
4760 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00004761 errno = 0;
4762 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004763 if (c == (clock_t) -1)
4764 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004765 return Py_BuildValue("ddddd",
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00004766 (double)t.tms_utime / ticks_per_second,
4767 (double)t.tms_stime / ticks_per_second,
4768 (double)t.tms_cutime / ticks_per_second,
4769 (double)t.tms_cstime / ticks_per_second,
4770 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004771}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004772#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004773#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004774
4775
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004776#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004777#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004778static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004779posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004780{
4781 FILETIME create, exit, kernel, user;
4782 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004783 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004784 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4785 /* The fields of a FILETIME structure are the hi and lo part
4786 of a 64-bit value expressed in 100 nanosecond units.
4787 1e7 is one second in such units; 1e-7 the inverse.
4788 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4789 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004790 return Py_BuildValue(
4791 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004792 (double)(user.dwHighDateTime*429.4967296 +
4793 user.dwLowDateTime*1e-7),
Christian Heimes68f5fbe2008-02-14 08:27:37 +00004794 (double)(kernel.dwHighDateTime*429.4967296 +
4795 kernel.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004796 (double)0,
4797 (double)0,
4798 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004799}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004800#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004801
4802#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004803PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004804"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004805Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004806#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004807
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004808
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004809#ifdef HAVE_GETSID
4810PyDoc_STRVAR(posix_getsid__doc__,
4811"getsid(pid) -> sid\n\n\
4812Call the system call getsid().");
4813
4814static PyObject *
4815posix_getsid(PyObject *self, PyObject *args)
4816{
Christian Heimes292d3512008-02-03 16:51:08 +00004817 pid_t pid;
4818 int sid;
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004819 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
4820 return NULL;
4821 sid = getsid(pid);
4822 if (sid < 0)
4823 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00004824 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004825}
4826#endif /* HAVE_GETSID */
4827
4828
Guido van Rossumb6775db1994-08-01 11:34:53 +00004829#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004830PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004831"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004832Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004833
Barry Warsaw53699e91996-12-10 23:23:01 +00004834static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004835posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004836{
Guido van Rossum687dd131993-05-17 08:34:16 +00004837 if (setsid() < 0)
4838 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004839 Py_INCREF(Py_None);
4840 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004841}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004842#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004843
Guido van Rossumb6775db1994-08-01 11:34:53 +00004844#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004845PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004846"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004847Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004848
Barry Warsaw53699e91996-12-10 23:23:01 +00004849static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004850posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004851{
Christian Heimes292d3512008-02-03 16:51:08 +00004852 pid_t pid;
4853 int pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004854 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004855 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004856 if (setpgid(pid, pgrp) < 0)
4857 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004858 Py_INCREF(Py_None);
4859 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004860}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004861#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004862
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004863
Guido van Rossumb6775db1994-08-01 11:34:53 +00004864#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004865PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004866"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004867Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004868
Barry Warsaw53699e91996-12-10 23:23:01 +00004869static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004870posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004871{
Christian Heimes15ebc882008-02-04 18:48:49 +00004872 int fd;
4873 pid_t pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004874 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004875 return NULL;
4876 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004877 if (pgid < 0)
4878 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00004879 return PyLong_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004880}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004881#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004882
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004883
Guido van Rossumb6775db1994-08-01 11:34:53 +00004884#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004885PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004886"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004887Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004888
Barry Warsaw53699e91996-12-10 23:23:01 +00004889static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004890posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004891{
4892 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004893 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004894 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004895 if (tcsetpgrp(fd, pgid) < 0)
4896 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004897 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004898 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004899}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004900#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004901
Guido van Rossum687dd131993-05-17 08:34:16 +00004902/* Functions acting on file descriptors */
4903
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004904PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004905"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004906Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004907
Barry Warsaw53699e91996-12-10 23:23:01 +00004908static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004909posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004910{
Martin v. Löwis011e8422009-05-05 04:43:17 +00004911 PyObject *ofile;
4912 char *file;
Guido van Rossum687dd131993-05-17 08:34:16 +00004913 int flag;
4914 int mode = 0777;
4915 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004916
4917#ifdef MS_WINDOWS
4918 if (unicode_file_names()) {
4919 PyUnicodeObject *po;
4920 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4921 Py_BEGIN_ALLOW_THREADS
4922 /* PyUnicode_AS_UNICODE OK without thread
4923 lock as it is a simple dereference. */
4924 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4925 Py_END_ALLOW_THREADS
4926 if (fd < 0)
4927 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00004928 return PyLong_FromLong((long)fd);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004929 }
4930 /* Drop the argument parsing error as narrow strings
4931 are also valid. */
4932 PyErr_Clear();
4933 }
4934#endif
4935
Martin v. Löwis011e8422009-05-05 04:43:17 +00004936 if (!PyArg_ParseTuple(args, "O&i|i",
4937 PyUnicode_FSConverter, &ofile,
Mark Hammondef8b6542001-05-13 08:04:26 +00004938 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004939 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004940 file = bytes2str(ofile, 1);
Barry Warsaw53699e91996-12-10 23:23:01 +00004941 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004942 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004943 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004944 if (fd < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004945 return posix_error_with_allocated_filename(ofile);
4946 release_bytes(ofile);
Christian Heimes217cfd12007-12-02 14:31:20 +00004947 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004948}
4949
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004950
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004951PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004952"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004953Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004954
Barry Warsaw53699e91996-12-10 23:23:01 +00004955static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004956posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004957{
4958 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004959 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004960 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00004961 if (!_PyVerify_fd(fd))
4962 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004963 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004964 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004965 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004966 if (res < 0)
4967 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004968 Py_INCREF(Py_None);
4969 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004970}
4971
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004972
Christian Heimesfdab48e2008-01-20 09:06:41 +00004973PyDoc_STRVAR(posix_closerange__doc__,
4974"closerange(fd_low, fd_high)\n\n\
4975Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
4976
4977static PyObject *
4978posix_closerange(PyObject *self, PyObject *args)
4979{
4980 int fd_from, fd_to, i;
4981 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
4982 return NULL;
4983 Py_BEGIN_ALLOW_THREADS
4984 for (i = fd_from; i < fd_to; i++)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00004985 if (_PyVerify_fd(i))
4986 close(i);
Christian Heimesfdab48e2008-01-20 09:06:41 +00004987 Py_END_ALLOW_THREADS
4988 Py_RETURN_NONE;
4989}
4990
4991
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004992PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004993"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004994Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004995
Barry Warsaw53699e91996-12-10 23:23:01 +00004996static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004997posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004998{
4999 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005000 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005001 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00005002 if (!_PyVerify_fd(fd))
5003 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005004 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005005 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005006 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005007 if (fd < 0)
5008 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00005009 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005010}
5011
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005012
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005013PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005014"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005015Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005016
Barry Warsaw53699e91996-12-10 23:23:01 +00005017static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005018posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005019{
5020 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005021 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005022 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00005023 if (!_PyVerify_fd_dup2(fd, fd2))
5024 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005025 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005026 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005027 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005028 if (res < 0)
5029 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005030 Py_INCREF(Py_None);
5031 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005032}
5033
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005034
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005035PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005036"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005037Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005038
Barry Warsaw53699e91996-12-10 23:23:01 +00005039static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005040posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005041{
5042 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005043#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005044 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005045#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005046 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005047#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005048 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005049 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005050 return NULL;
5051#ifdef SEEK_SET
5052 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5053 switch (how) {
5054 case 0: how = SEEK_SET; break;
5055 case 1: how = SEEK_CUR; break;
5056 case 2: how = SEEK_END; break;
5057 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005058#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005059
5060#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +00005061 pos = PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005062#else
5063 pos = PyLong_Check(posobj) ?
Christian Heimes217cfd12007-12-02 14:31:20 +00005064 PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005065#endif
5066 if (PyErr_Occurred())
5067 return NULL;
5068
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00005069 if (!_PyVerify_fd(fd))
5070 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005071 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005072#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005073 res = _lseeki64(fd, pos, how);
5074#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005075 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005076#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005077 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005078 if (res < 0)
5079 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005080
5081#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +00005082 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005083#else
5084 return PyLong_FromLongLong(res);
5085#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005086}
5087
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005088
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005089PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005090"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005091Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005092
Barry Warsaw53699e91996-12-10 23:23:01 +00005093static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005094posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005095{
Guido van Rossum572dbf82007-04-27 23:53:51 +00005096 int fd, size;
5097 Py_ssize_t n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005098 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005099 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005100 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00005101 if (size < 0) {
5102 errno = EINVAL;
5103 return posix_error();
5104 }
Christian Heimes72b710a2008-05-26 13:28:38 +00005105 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005106 if (buffer == NULL)
5107 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00005108 if (!_PyVerify_fd(fd))
5109 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005110 Py_BEGIN_ALLOW_THREADS
Christian Heimes72b710a2008-05-26 13:28:38 +00005111 n = read(fd, PyBytes_AS_STRING(buffer), size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005112 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005113 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005114 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005115 return posix_error();
5116 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005117 if (n != size)
Christian Heimes72b710a2008-05-26 13:28:38 +00005118 _PyBytes_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005119 return buffer;
5120}
5121
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005122
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005123PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005124"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005125Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005126
Barry Warsaw53699e91996-12-10 23:23:01 +00005127static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005128posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005129{
Martin v. Löwis423be952008-08-13 15:53:07 +00005130 Py_buffer pbuf;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005131 int fd;
5132 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005133
Antoine Pitrou9cadb1b2008-09-15 23:02:56 +00005134 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
Guido van Rossum687dd131993-05-17 08:34:16 +00005135 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00005136 if (!_PyVerify_fd(fd))
5137 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005138 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis423be952008-08-13 15:53:07 +00005139 size = write(fd, pbuf.buf, (size_t)pbuf.len);
Barry Warsaw53699e91996-12-10 23:23:01 +00005140 Py_END_ALLOW_THREADS
Martin v. Löwis423be952008-08-13 15:53:07 +00005141 PyBuffer_Release(&pbuf);
Guido van Rossum687dd131993-05-17 08:34:16 +00005142 if (size < 0)
5143 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00005144 return PyLong_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005145}
5146
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005147
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005148PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005149"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005150Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005151
Barry Warsaw53699e91996-12-10 23:23:01 +00005152static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005153posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005154{
5155 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005156 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005157 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005158 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005159 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005160#ifdef __VMS
5161 /* on OpenVMS we must ensure that all bytes are written to the file */
5162 fsync(fd);
5163#endif
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00005164 if (!_PyVerify_fd(fd))
5165 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005166 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005167 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005168 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00005169 if (res != 0) {
5170#ifdef MS_WINDOWS
5171 return win32_error("fstat", NULL);
5172#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005173 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005174#endif
5175 }
Tim Peters5aa91602002-01-30 05:46:57 +00005176
Martin v. Löwis14694662006-02-03 12:54:16 +00005177 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005178}
5179
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005180PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005181"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005182Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005183connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005184
5185static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005186posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005187{
5188 int fd;
5189 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5190 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00005191 if (!_PyVerify_fd(fd))
5192 return PyBool_FromLong(0);
Fred Drake106c1a02002-04-23 15:58:02 +00005193 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005194}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005195
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005196#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005197PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005198"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005199Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005200
Barry Warsaw53699e91996-12-10 23:23:01 +00005201static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005202posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005203{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005204#if defined(PYOS_OS2)
5205 HFILE read, write;
5206 APIRET rc;
5207
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005208 Py_BEGIN_ALLOW_THREADS
5209 rc = DosCreatePipe( &read, &write, 4096);
5210 Py_END_ALLOW_THREADS
5211 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005212 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005213
5214 return Py_BuildValue("(ii)", read, write);
5215#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005216#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005217 int fds[2];
5218 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005219 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005220 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005221 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005222 if (res != 0)
5223 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005224 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005225#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005226 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005227 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005228 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005229 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005230 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005231 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005232 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005233 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005234 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5235 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005236 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005237#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005238#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005239}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005240#endif /* HAVE_PIPE */
5241
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005242
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005243#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005244PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005245"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005246Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005247
Barry Warsaw53699e91996-12-10 23:23:01 +00005248static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005249posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005250{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005251 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005252 int mode = 0666;
5253 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005254 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005255 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005256 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005257 res = mkfifo(filename, mode);
5258 Py_END_ALLOW_THREADS
5259 if (res < 0)
5260 return posix_error();
5261 Py_INCREF(Py_None);
5262 return Py_None;
5263}
5264#endif
5265
5266
Neal Norwitz11690112002-07-30 01:08:28 +00005267#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005268PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005269"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005270Create a filesystem node (file, device special file or named pipe)\n\
5271named filename. mode specifies both the permissions to use and the\n\
5272type of node to be created, being combined (bitwise OR) with one of\n\
5273S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005274device defines the newly created device special file (probably using\n\
5275os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005276
5277
5278static PyObject *
5279posix_mknod(PyObject *self, PyObject *args)
5280{
5281 char *filename;
5282 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005283 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005284 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005285 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005286 return NULL;
5287 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005288 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005289 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005290 if (res < 0)
5291 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005292 Py_INCREF(Py_None);
5293 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005294}
5295#endif
5296
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005297#ifdef HAVE_DEVICE_MACROS
5298PyDoc_STRVAR(posix_major__doc__,
5299"major(device) -> major number\n\
5300Extracts a device major number from a raw device number.");
5301
5302static PyObject *
5303posix_major(PyObject *self, PyObject *args)
5304{
5305 int device;
5306 if (!PyArg_ParseTuple(args, "i:major", &device))
5307 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +00005308 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005309}
5310
5311PyDoc_STRVAR(posix_minor__doc__,
5312"minor(device) -> minor number\n\
5313Extracts a device minor number from a raw device number.");
5314
5315static PyObject *
5316posix_minor(PyObject *self, PyObject *args)
5317{
5318 int device;
5319 if (!PyArg_ParseTuple(args, "i:minor", &device))
5320 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +00005321 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005322}
5323
5324PyDoc_STRVAR(posix_makedev__doc__,
5325"makedev(major, minor) -> device number\n\
5326Composes a raw device number from the major and minor device numbers.");
5327
5328static PyObject *
5329posix_makedev(PyObject *self, PyObject *args)
5330{
5331 int major, minor;
5332 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5333 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +00005334 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005335}
5336#endif /* device macros */
5337
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005338
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005339#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005340PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005341"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005342Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005343
Barry Warsaw53699e91996-12-10 23:23:01 +00005344static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005345posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005346{
5347 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005348 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005349 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005350 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005351
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005352 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005353 return NULL;
5354
5355#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +00005356 length = PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005357#else
5358 length = PyLong_Check(lenobj) ?
Christian Heimes217cfd12007-12-02 14:31:20 +00005359 PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005360#endif
5361 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005362 return NULL;
5363
Barry Warsaw53699e91996-12-10 23:23:01 +00005364 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005365 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005366 Py_END_ALLOW_THREADS
Benjamin Peterson9053d752009-01-19 17:53:36 +00005367 if (res < 0)
5368 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005369 Py_INCREF(Py_None);
5370 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005371}
5372#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005373
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005374#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005375PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005376"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005377Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005378
Fred Drake762e2061999-08-26 17:23:54 +00005379/* Save putenv() parameters as values here, so we can collect them when they
5380 * get re-set with another call for the same key. */
5381static PyObject *posix_putenv_garbage;
5382
Tim Peters5aa91602002-01-30 05:46:57 +00005383static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005384posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005385{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005386#ifdef MS_WINDOWS
5387 wchar_t *s1, *s2;
5388 wchar_t *newenv;
5389#else
Martin v. Löwis011e8422009-05-05 04:43:17 +00005390 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005391 char *s1, *s2;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005392 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005393#endif
Fred Drake762e2061999-08-26 17:23:54 +00005394 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005395 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005396
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005397#ifdef MS_WINDOWS
Martin v. Löwis011e8422009-05-05 04:43:17 +00005398 if (!PyArg_ParseTuple(args,
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005399 "uu:putenv",
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005400 &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005401 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005402#else
5403 if (!PyArg_ParseTuple(args,
5404 "O&O&:putenv",
5405 PyUnicode_FSConverter, &os1,
5406 PyUnicode_FSConverter, &os2))
5407 return NULL;
5408 s1 = bytes2str(os1, 1);
5409 s2 = bytes2str(os2, 1);
5410#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005411
5412#if defined(PYOS_OS2)
5413 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5414 APIRET rc;
5415
Guido van Rossumd48f2521997-12-05 22:19:34 +00005416 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5417 if (rc != NO_ERROR)
5418 return os2_error(rc);
5419
5420 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5421 APIRET rc;
5422
Guido van Rossumd48f2521997-12-05 22:19:34 +00005423 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5424 if (rc != NO_ERROR)
5425 return os2_error(rc);
5426 } else {
5427#endif
Fred Drake762e2061999-08-26 17:23:54 +00005428 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005429 /* len includes space for a trailing \0; the size arg to
Christian Heimes72b710a2008-05-26 13:28:38 +00005430 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005431#ifdef MS_WINDOWS
5432 len = wcslen(s1) + wcslen(s2) + 2;
5433 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
5434#else
5435 len = strlen(s1) + strlen(s2) + 2;
Christian Heimes72b710a2008-05-26 13:28:38 +00005436 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005437#endif
Fred Drake762e2061999-08-26 17:23:54 +00005438 if (newstr == NULL)
5439 return PyErr_NoMemory();
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005440#ifdef MS_WINDOWS
5441 newenv = PyUnicode_AsUnicode(newstr);
5442 _snwprintf(newenv, len, L"%s=%s", s1, s2);
5443 if (_wputenv(newenv)) {
5444 Py_DECREF(newstr);
5445 posix_error();
5446 return NULL;
5447 }
5448#else
Christian Heimes72b710a2008-05-26 13:28:38 +00005449 newenv = PyBytes_AS_STRING(newstr);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005450 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
5451 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005452 Py_DECREF(newstr);
Martin v. Löwis011e8422009-05-05 04:43:17 +00005453 release_bytes(os1);
5454 release_bytes(os2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005455 posix_error();
5456 return NULL;
5457 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005458#endif
Fred Drake762e2061999-08-26 17:23:54 +00005459 /* Install the first arg and newstr in posix_putenv_garbage;
5460 * this will cause previous value to be collected. This has to
5461 * happen after the real putenv() call because the old value
5462 * was still accessible until then. */
5463 if (PyDict_SetItem(posix_putenv_garbage,
5464 PyTuple_GET_ITEM(args, 0), newstr)) {
5465 /* really not much we can do; just leak */
5466 PyErr_Clear();
5467 }
5468 else {
5469 Py_DECREF(newstr);
5470 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005471
5472#if defined(PYOS_OS2)
5473 }
5474#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00005475#ifndef MS_WINDOWS
5476 release_bytes(os1);
5477 release_bytes(os2);
5478#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005479 Py_INCREF(Py_None);
5480 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005481}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005482#endif /* putenv */
5483
Guido van Rossumc524d952001-10-19 01:31:59 +00005484#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005485PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005486"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005487Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005488
5489static PyObject *
5490posix_unsetenv(PyObject *self, PyObject *args)
5491{
5492 char *s1;
5493
5494 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5495 return NULL;
5496
5497 unsetenv(s1);
5498
5499 /* Remove the key from posix_putenv_garbage;
5500 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005501 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005502 * old value was still accessible until then.
5503 */
5504 if (PyDict_DelItem(posix_putenv_garbage,
5505 PyTuple_GET_ITEM(args, 0))) {
5506 /* really not much we can do; just leak */
5507 PyErr_Clear();
5508 }
5509
5510 Py_INCREF(Py_None);
5511 return Py_None;
5512}
5513#endif /* unsetenv */
5514
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005515PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005516"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005517Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005518
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005519static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005520posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005521{
5522 int code;
5523 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005524 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005525 return NULL;
5526 message = strerror(code);
5527 if (message == NULL) {
5528 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005529 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005530 return NULL;
5531 }
Neal Norwitz93c56822007-08-26 07:10:06 +00005532 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00005533}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005534
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005535
Guido van Rossumc9641791998-08-04 15:26:23 +00005536#ifdef HAVE_SYS_WAIT_H
5537
Fred Drake106c1a02002-04-23 15:58:02 +00005538#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005539PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005540"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005541Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005542
5543static PyObject *
5544posix_WCOREDUMP(PyObject *self, PyObject *args)
5545{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005546 WAIT_TYPE status;
5547 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005548
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005549 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00005550 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005551
5552 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005553}
5554#endif /* WCOREDUMP */
5555
5556#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005557PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005558"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005559Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005560job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005561
5562static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005563posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005564{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005565 WAIT_TYPE status;
5566 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005567
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005568 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00005569 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005570
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005571 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005572}
5573#endif /* WIFCONTINUED */
5574
Guido van Rossumc9641791998-08-04 15:26:23 +00005575#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005576PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005577"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005578Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005579
5580static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005581posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005582{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005583 WAIT_TYPE status;
5584 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005585
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005586 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005587 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005588
Fred Drake106c1a02002-04-23 15:58:02 +00005589 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005590}
5591#endif /* WIFSTOPPED */
5592
5593#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005594PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005595"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005596Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005597
5598static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005599posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005600{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005601 WAIT_TYPE status;
5602 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005603
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005604 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005605 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005606
Fred Drake106c1a02002-04-23 15:58:02 +00005607 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005608}
5609#endif /* WIFSIGNALED */
5610
5611#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005612PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005613"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005614Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005615system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005616
5617static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005618posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005619{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005620 WAIT_TYPE status;
5621 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005622
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005623 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005624 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005625
Fred Drake106c1a02002-04-23 15:58:02 +00005626 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005627}
5628#endif /* WIFEXITED */
5629
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005630#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005631PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005632"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005633Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005634
5635static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005636posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005637{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005638 WAIT_TYPE status;
5639 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005640
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005641 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005642 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005643
Guido van Rossumc9641791998-08-04 15:26:23 +00005644 return Py_BuildValue("i", WEXITSTATUS(status));
5645}
5646#endif /* WEXITSTATUS */
5647
5648#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005649PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005650"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005651Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005652value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005653
5654static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005655posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005656{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005657 WAIT_TYPE status;
5658 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005659
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005660 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005661 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005662
Guido van Rossumc9641791998-08-04 15:26:23 +00005663 return Py_BuildValue("i", WTERMSIG(status));
5664}
5665#endif /* WTERMSIG */
5666
5667#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005668PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005669"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005670Return the signal that stopped the process that provided\n\
5671the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005672
5673static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005674posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005675{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005676 WAIT_TYPE status;
5677 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005678
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005679 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005680 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005681
Guido van Rossumc9641791998-08-04 15:26:23 +00005682 return Py_BuildValue("i", WSTOPSIG(status));
5683}
5684#endif /* WSTOPSIG */
5685
5686#endif /* HAVE_SYS_WAIT_H */
5687
5688
Thomas Wouters477c8d52006-05-27 19:21:47 +00005689#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005690#ifdef _SCO_DS
5691/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5692 needed definitions in sys/statvfs.h */
5693#define _SVID3
5694#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005695#include <sys/statvfs.h>
5696
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005697static PyObject*
5698_pystatvfs_fromstructstatvfs(struct statvfs st) {
5699 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5700 if (v == NULL)
5701 return NULL;
5702
5703#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +00005704 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
5705 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
5706 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
5707 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
5708 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
5709 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
5710 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
5711 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
5712 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
5713 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005714#else
Christian Heimes217cfd12007-12-02 14:31:20 +00005715 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
5716 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005717 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005718 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005719 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005720 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005721 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005722 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005723 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005724 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005725 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005726 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005727 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005728 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Christian Heimes217cfd12007-12-02 14:31:20 +00005729 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
5730 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005731#endif
5732
5733 return v;
5734}
5735
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005736PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005737"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005738Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005739
5740static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005741posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005742{
5743 int fd, res;
5744 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005745
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005746 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005747 return NULL;
5748 Py_BEGIN_ALLOW_THREADS
5749 res = fstatvfs(fd, &st);
5750 Py_END_ALLOW_THREADS
5751 if (res != 0)
5752 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005753
5754 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005755}
Thomas Wouters477c8d52006-05-27 19:21:47 +00005756#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005757
5758
Thomas Wouters477c8d52006-05-27 19:21:47 +00005759#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005760#include <sys/statvfs.h>
5761
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005762PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005763"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005764Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005765
5766static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005767posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005768{
5769 char *path;
5770 int res;
5771 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005772 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005773 return NULL;
5774 Py_BEGIN_ALLOW_THREADS
5775 res = statvfs(path, &st);
5776 Py_END_ALLOW_THREADS
5777 if (res != 0)
5778 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005779
5780 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005781}
5782#endif /* HAVE_STATVFS */
5783
Fred Drakec9680921999-12-13 16:37:25 +00005784/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5785 * It maps strings representing configuration variable names to
5786 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005787 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005788 * rarely-used constants. There are three separate tables that use
5789 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005790 *
5791 * This code is always included, even if none of the interfaces that
5792 * need it are included. The #if hackery needed to avoid it would be
5793 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005794 */
5795struct constdef {
5796 char *name;
5797 long value;
5798};
5799
Fred Drake12c6e2d1999-12-14 21:25:03 +00005800static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005801conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005802 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005803{
Christian Heimes217cfd12007-12-02 14:31:20 +00005804 if (PyLong_Check(arg)) {
5805 *valuep = PyLong_AS_LONG(arg);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005806 return 1;
5807 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00005808 else {
Fred Drake12c6e2d1999-12-14 21:25:03 +00005809 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005810 size_t lo = 0;
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005811 size_t mid;
Fred Drake699f3522000-06-29 21:12:41 +00005812 size_t hi = tablesize;
5813 int cmp;
Guido van Rossumbce56a62007-05-10 18:04:33 +00005814 const char *confname;
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005815 if (!PyUnicode_Check(arg)) {
Guido van Rossumbce56a62007-05-10 18:04:33 +00005816 PyErr_SetString(PyExc_TypeError,
5817 "configuration names must be strings or integers");
5818 return 0;
5819 }
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +00005820 confname = _PyUnicode_AsString(arg);
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005821 if (confname == NULL)
5822 return 0;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005823 while (lo < hi) {
5824 mid = (lo + hi) / 2;
5825 cmp = strcmp(confname, table[mid].name);
5826 if (cmp < 0)
5827 hi = mid;
5828 else if (cmp > 0)
5829 lo = mid + 1;
5830 else {
5831 *valuep = table[mid].value;
5832 return 1;
5833 }
5834 }
5835 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
Guido van Rossumbce56a62007-05-10 18:04:33 +00005836 return 0;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005837 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00005838}
5839
5840
5841#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5842static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005843#ifdef _PC_ABI_AIO_XFER_MAX
5844 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5845#endif
5846#ifdef _PC_ABI_ASYNC_IO
5847 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5848#endif
Fred Drakec9680921999-12-13 16:37:25 +00005849#ifdef _PC_ASYNC_IO
5850 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5851#endif
5852#ifdef _PC_CHOWN_RESTRICTED
5853 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5854#endif
5855#ifdef _PC_FILESIZEBITS
5856 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5857#endif
5858#ifdef _PC_LAST
5859 {"PC_LAST", _PC_LAST},
5860#endif
5861#ifdef _PC_LINK_MAX
5862 {"PC_LINK_MAX", _PC_LINK_MAX},
5863#endif
5864#ifdef _PC_MAX_CANON
5865 {"PC_MAX_CANON", _PC_MAX_CANON},
5866#endif
5867#ifdef _PC_MAX_INPUT
5868 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5869#endif
5870#ifdef _PC_NAME_MAX
5871 {"PC_NAME_MAX", _PC_NAME_MAX},
5872#endif
5873#ifdef _PC_NO_TRUNC
5874 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5875#endif
5876#ifdef _PC_PATH_MAX
5877 {"PC_PATH_MAX", _PC_PATH_MAX},
5878#endif
5879#ifdef _PC_PIPE_BUF
5880 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5881#endif
5882#ifdef _PC_PRIO_IO
5883 {"PC_PRIO_IO", _PC_PRIO_IO},
5884#endif
5885#ifdef _PC_SOCK_MAXBUF
5886 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5887#endif
5888#ifdef _PC_SYNC_IO
5889 {"PC_SYNC_IO", _PC_SYNC_IO},
5890#endif
5891#ifdef _PC_VDISABLE
5892 {"PC_VDISABLE", _PC_VDISABLE},
5893#endif
5894};
5895
Fred Drakec9680921999-12-13 16:37:25 +00005896static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005897conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005898{
5899 return conv_confname(arg, valuep, posix_constants_pathconf,
5900 sizeof(posix_constants_pathconf)
5901 / sizeof(struct constdef));
5902}
5903#endif
5904
5905#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005906PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005907"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005908Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005909If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005910
5911static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005912posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005913{
5914 PyObject *result = NULL;
5915 int name, fd;
5916
Fred Drake12c6e2d1999-12-14 21:25:03 +00005917 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5918 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005919 long limit;
5920
5921 errno = 0;
5922 limit = fpathconf(fd, name);
5923 if (limit == -1 && errno != 0)
5924 posix_error();
5925 else
Christian Heimes217cfd12007-12-02 14:31:20 +00005926 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00005927 }
5928 return result;
5929}
5930#endif
5931
5932
5933#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005934PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005935"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005936Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005937If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005938
5939static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005940posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005941{
5942 PyObject *result = NULL;
5943 int name;
5944 char *path;
5945
5946 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5947 conv_path_confname, &name)) {
5948 long limit;
5949
5950 errno = 0;
5951 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005952 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005953 if (errno == EINVAL)
5954 /* could be a path or name problem */
5955 posix_error();
5956 else
5957 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005958 }
Fred Drakec9680921999-12-13 16:37:25 +00005959 else
Christian Heimes217cfd12007-12-02 14:31:20 +00005960 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00005961 }
5962 return result;
5963}
5964#endif
5965
5966#ifdef HAVE_CONFSTR
5967static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005968#ifdef _CS_ARCHITECTURE
5969 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5970#endif
5971#ifdef _CS_HOSTNAME
5972 {"CS_HOSTNAME", _CS_HOSTNAME},
5973#endif
5974#ifdef _CS_HW_PROVIDER
5975 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5976#endif
5977#ifdef _CS_HW_SERIAL
5978 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5979#endif
5980#ifdef _CS_INITTAB_NAME
5981 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5982#endif
Fred Drakec9680921999-12-13 16:37:25 +00005983#ifdef _CS_LFS64_CFLAGS
5984 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5985#endif
5986#ifdef _CS_LFS64_LDFLAGS
5987 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5988#endif
5989#ifdef _CS_LFS64_LIBS
5990 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5991#endif
5992#ifdef _CS_LFS64_LINTFLAGS
5993 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5994#endif
5995#ifdef _CS_LFS_CFLAGS
5996 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5997#endif
5998#ifdef _CS_LFS_LDFLAGS
5999 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6000#endif
6001#ifdef _CS_LFS_LIBS
6002 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6003#endif
6004#ifdef _CS_LFS_LINTFLAGS
6005 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6006#endif
Fred Draked86ed291999-12-15 15:34:33 +00006007#ifdef _CS_MACHINE
6008 {"CS_MACHINE", _CS_MACHINE},
6009#endif
Fred Drakec9680921999-12-13 16:37:25 +00006010#ifdef _CS_PATH
6011 {"CS_PATH", _CS_PATH},
6012#endif
Fred Draked86ed291999-12-15 15:34:33 +00006013#ifdef _CS_RELEASE
6014 {"CS_RELEASE", _CS_RELEASE},
6015#endif
6016#ifdef _CS_SRPC_DOMAIN
6017 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6018#endif
6019#ifdef _CS_SYSNAME
6020 {"CS_SYSNAME", _CS_SYSNAME},
6021#endif
6022#ifdef _CS_VERSION
6023 {"CS_VERSION", _CS_VERSION},
6024#endif
Fred Drakec9680921999-12-13 16:37:25 +00006025#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6026 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6027#endif
6028#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6029 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6030#endif
6031#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6032 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6033#endif
6034#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6035 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6036#endif
6037#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6038 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6039#endif
6040#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6041 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6042#endif
6043#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6044 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6045#endif
6046#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6047 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6048#endif
6049#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6050 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6051#endif
6052#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6053 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6054#endif
6055#ifdef _CS_XBS5_LP64_OFF64_LIBS
6056 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6057#endif
6058#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6059 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6060#endif
6061#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6062 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6063#endif
6064#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6065 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6066#endif
6067#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6068 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6069#endif
6070#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6071 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6072#endif
Fred Draked86ed291999-12-15 15:34:33 +00006073#ifdef _MIPS_CS_AVAIL_PROCESSORS
6074 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6075#endif
6076#ifdef _MIPS_CS_BASE
6077 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6078#endif
6079#ifdef _MIPS_CS_HOSTID
6080 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6081#endif
6082#ifdef _MIPS_CS_HW_NAME
6083 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6084#endif
6085#ifdef _MIPS_CS_NUM_PROCESSORS
6086 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6087#endif
6088#ifdef _MIPS_CS_OSREL_MAJ
6089 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6090#endif
6091#ifdef _MIPS_CS_OSREL_MIN
6092 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6093#endif
6094#ifdef _MIPS_CS_OSREL_PATCH
6095 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6096#endif
6097#ifdef _MIPS_CS_OS_NAME
6098 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6099#endif
6100#ifdef _MIPS_CS_OS_PROVIDER
6101 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6102#endif
6103#ifdef _MIPS_CS_PROCESSORS
6104 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6105#endif
6106#ifdef _MIPS_CS_SERIAL
6107 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6108#endif
6109#ifdef _MIPS_CS_VENDOR
6110 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6111#endif
Fred Drakec9680921999-12-13 16:37:25 +00006112};
6113
6114static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006115conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006116{
6117 return conv_confname(arg, valuep, posix_constants_confstr,
6118 sizeof(posix_constants_confstr)
6119 / sizeof(struct constdef));
6120}
6121
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006122PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006123"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006124Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006125
6126static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006127posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006128{
6129 PyObject *result = NULL;
6130 int name;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006131 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00006132
6133 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006134 int len;
Fred Drakec9680921999-12-13 16:37:25 +00006135
Fred Drakec9680921999-12-13 16:37:25 +00006136 errno = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006137 len = confstr(name, buffer, sizeof(buffer));
6138 if (len == 0) {
6139 if (errno) {
6140 posix_error();
6141 }
6142 else {
6143 result = Py_None;
6144 Py_INCREF(Py_None);
6145 }
Fred Drakec9680921999-12-13 16:37:25 +00006146 }
6147 else {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006148 if ((unsigned int)len >= sizeof(buffer)) {
Neal Norwitz93c56822007-08-26 07:10:06 +00006149 result = PyUnicode_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006150 if (result != NULL)
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +00006151 confstr(name, _PyUnicode_AsString(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00006152 }
6153 else
Neal Norwitz93c56822007-08-26 07:10:06 +00006154 result = PyUnicode_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006155 }
6156 }
6157 return result;
6158}
6159#endif
6160
6161
6162#ifdef HAVE_SYSCONF
6163static struct constdef posix_constants_sysconf[] = {
6164#ifdef _SC_2_CHAR_TERM
6165 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6166#endif
6167#ifdef _SC_2_C_BIND
6168 {"SC_2_C_BIND", _SC_2_C_BIND},
6169#endif
6170#ifdef _SC_2_C_DEV
6171 {"SC_2_C_DEV", _SC_2_C_DEV},
6172#endif
6173#ifdef _SC_2_C_VERSION
6174 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6175#endif
6176#ifdef _SC_2_FORT_DEV
6177 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6178#endif
6179#ifdef _SC_2_FORT_RUN
6180 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6181#endif
6182#ifdef _SC_2_LOCALEDEF
6183 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6184#endif
6185#ifdef _SC_2_SW_DEV
6186 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6187#endif
6188#ifdef _SC_2_UPE
6189 {"SC_2_UPE", _SC_2_UPE},
6190#endif
6191#ifdef _SC_2_VERSION
6192 {"SC_2_VERSION", _SC_2_VERSION},
6193#endif
Fred Draked86ed291999-12-15 15:34:33 +00006194#ifdef _SC_ABI_ASYNCHRONOUS_IO
6195 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6196#endif
6197#ifdef _SC_ACL
6198 {"SC_ACL", _SC_ACL},
6199#endif
Fred Drakec9680921999-12-13 16:37:25 +00006200#ifdef _SC_AIO_LISTIO_MAX
6201 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6202#endif
Fred Drakec9680921999-12-13 16:37:25 +00006203#ifdef _SC_AIO_MAX
6204 {"SC_AIO_MAX", _SC_AIO_MAX},
6205#endif
6206#ifdef _SC_AIO_PRIO_DELTA_MAX
6207 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6208#endif
6209#ifdef _SC_ARG_MAX
6210 {"SC_ARG_MAX", _SC_ARG_MAX},
6211#endif
6212#ifdef _SC_ASYNCHRONOUS_IO
6213 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6214#endif
6215#ifdef _SC_ATEXIT_MAX
6216 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6217#endif
Fred Draked86ed291999-12-15 15:34:33 +00006218#ifdef _SC_AUDIT
6219 {"SC_AUDIT", _SC_AUDIT},
6220#endif
Fred Drakec9680921999-12-13 16:37:25 +00006221#ifdef _SC_AVPHYS_PAGES
6222 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6223#endif
6224#ifdef _SC_BC_BASE_MAX
6225 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6226#endif
6227#ifdef _SC_BC_DIM_MAX
6228 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6229#endif
6230#ifdef _SC_BC_SCALE_MAX
6231 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6232#endif
6233#ifdef _SC_BC_STRING_MAX
6234 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6235#endif
Fred Draked86ed291999-12-15 15:34:33 +00006236#ifdef _SC_CAP
6237 {"SC_CAP", _SC_CAP},
6238#endif
Fred Drakec9680921999-12-13 16:37:25 +00006239#ifdef _SC_CHARCLASS_NAME_MAX
6240 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6241#endif
6242#ifdef _SC_CHAR_BIT
6243 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6244#endif
6245#ifdef _SC_CHAR_MAX
6246 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6247#endif
6248#ifdef _SC_CHAR_MIN
6249 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6250#endif
6251#ifdef _SC_CHILD_MAX
6252 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6253#endif
6254#ifdef _SC_CLK_TCK
6255 {"SC_CLK_TCK", _SC_CLK_TCK},
6256#endif
6257#ifdef _SC_COHER_BLKSZ
6258 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6259#endif
6260#ifdef _SC_COLL_WEIGHTS_MAX
6261 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6262#endif
6263#ifdef _SC_DCACHE_ASSOC
6264 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6265#endif
6266#ifdef _SC_DCACHE_BLKSZ
6267 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6268#endif
6269#ifdef _SC_DCACHE_LINESZ
6270 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6271#endif
6272#ifdef _SC_DCACHE_SZ
6273 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6274#endif
6275#ifdef _SC_DCACHE_TBLKSZ
6276 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6277#endif
6278#ifdef _SC_DELAYTIMER_MAX
6279 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6280#endif
6281#ifdef _SC_EQUIV_CLASS_MAX
6282 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6283#endif
6284#ifdef _SC_EXPR_NEST_MAX
6285 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6286#endif
6287#ifdef _SC_FSYNC
6288 {"SC_FSYNC", _SC_FSYNC},
6289#endif
6290#ifdef _SC_GETGR_R_SIZE_MAX
6291 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6292#endif
6293#ifdef _SC_GETPW_R_SIZE_MAX
6294 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6295#endif
6296#ifdef _SC_ICACHE_ASSOC
6297 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6298#endif
6299#ifdef _SC_ICACHE_BLKSZ
6300 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6301#endif
6302#ifdef _SC_ICACHE_LINESZ
6303 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6304#endif
6305#ifdef _SC_ICACHE_SZ
6306 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6307#endif
Fred Draked86ed291999-12-15 15:34:33 +00006308#ifdef _SC_INF
6309 {"SC_INF", _SC_INF},
6310#endif
Fred Drakec9680921999-12-13 16:37:25 +00006311#ifdef _SC_INT_MAX
6312 {"SC_INT_MAX", _SC_INT_MAX},
6313#endif
6314#ifdef _SC_INT_MIN
6315 {"SC_INT_MIN", _SC_INT_MIN},
6316#endif
6317#ifdef _SC_IOV_MAX
6318 {"SC_IOV_MAX", _SC_IOV_MAX},
6319#endif
Fred Draked86ed291999-12-15 15:34:33 +00006320#ifdef _SC_IP_SECOPTS
6321 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6322#endif
Fred Drakec9680921999-12-13 16:37:25 +00006323#ifdef _SC_JOB_CONTROL
6324 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6325#endif
Fred Draked86ed291999-12-15 15:34:33 +00006326#ifdef _SC_KERN_POINTERS
6327 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6328#endif
6329#ifdef _SC_KERN_SIM
6330 {"SC_KERN_SIM", _SC_KERN_SIM},
6331#endif
Fred Drakec9680921999-12-13 16:37:25 +00006332#ifdef _SC_LINE_MAX
6333 {"SC_LINE_MAX", _SC_LINE_MAX},
6334#endif
6335#ifdef _SC_LOGIN_NAME_MAX
6336 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6337#endif
6338#ifdef _SC_LOGNAME_MAX
6339 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6340#endif
6341#ifdef _SC_LONG_BIT
6342 {"SC_LONG_BIT", _SC_LONG_BIT},
6343#endif
Fred Draked86ed291999-12-15 15:34:33 +00006344#ifdef _SC_MAC
6345 {"SC_MAC", _SC_MAC},
6346#endif
Fred Drakec9680921999-12-13 16:37:25 +00006347#ifdef _SC_MAPPED_FILES
6348 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6349#endif
6350#ifdef _SC_MAXPID
6351 {"SC_MAXPID", _SC_MAXPID},
6352#endif
6353#ifdef _SC_MB_LEN_MAX
6354 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6355#endif
6356#ifdef _SC_MEMLOCK
6357 {"SC_MEMLOCK", _SC_MEMLOCK},
6358#endif
6359#ifdef _SC_MEMLOCK_RANGE
6360 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6361#endif
6362#ifdef _SC_MEMORY_PROTECTION
6363 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6364#endif
6365#ifdef _SC_MESSAGE_PASSING
6366 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6367#endif
Fred Draked86ed291999-12-15 15:34:33 +00006368#ifdef _SC_MMAP_FIXED_ALIGNMENT
6369 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6370#endif
Fred Drakec9680921999-12-13 16:37:25 +00006371#ifdef _SC_MQ_OPEN_MAX
6372 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6373#endif
6374#ifdef _SC_MQ_PRIO_MAX
6375 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6376#endif
Fred Draked86ed291999-12-15 15:34:33 +00006377#ifdef _SC_NACLS_MAX
6378 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6379#endif
Fred Drakec9680921999-12-13 16:37:25 +00006380#ifdef _SC_NGROUPS_MAX
6381 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6382#endif
6383#ifdef _SC_NL_ARGMAX
6384 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6385#endif
6386#ifdef _SC_NL_LANGMAX
6387 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6388#endif
6389#ifdef _SC_NL_MSGMAX
6390 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6391#endif
6392#ifdef _SC_NL_NMAX
6393 {"SC_NL_NMAX", _SC_NL_NMAX},
6394#endif
6395#ifdef _SC_NL_SETMAX
6396 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6397#endif
6398#ifdef _SC_NL_TEXTMAX
6399 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6400#endif
6401#ifdef _SC_NPROCESSORS_CONF
6402 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6403#endif
6404#ifdef _SC_NPROCESSORS_ONLN
6405 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6406#endif
Fred Draked86ed291999-12-15 15:34:33 +00006407#ifdef _SC_NPROC_CONF
6408 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6409#endif
6410#ifdef _SC_NPROC_ONLN
6411 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6412#endif
Fred Drakec9680921999-12-13 16:37:25 +00006413#ifdef _SC_NZERO
6414 {"SC_NZERO", _SC_NZERO},
6415#endif
6416#ifdef _SC_OPEN_MAX
6417 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6418#endif
6419#ifdef _SC_PAGESIZE
6420 {"SC_PAGESIZE", _SC_PAGESIZE},
6421#endif
6422#ifdef _SC_PAGE_SIZE
6423 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6424#endif
6425#ifdef _SC_PASS_MAX
6426 {"SC_PASS_MAX", _SC_PASS_MAX},
6427#endif
6428#ifdef _SC_PHYS_PAGES
6429 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6430#endif
6431#ifdef _SC_PII
6432 {"SC_PII", _SC_PII},
6433#endif
6434#ifdef _SC_PII_INTERNET
6435 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6436#endif
6437#ifdef _SC_PII_INTERNET_DGRAM
6438 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6439#endif
6440#ifdef _SC_PII_INTERNET_STREAM
6441 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6442#endif
6443#ifdef _SC_PII_OSI
6444 {"SC_PII_OSI", _SC_PII_OSI},
6445#endif
6446#ifdef _SC_PII_OSI_CLTS
6447 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6448#endif
6449#ifdef _SC_PII_OSI_COTS
6450 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6451#endif
6452#ifdef _SC_PII_OSI_M
6453 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6454#endif
6455#ifdef _SC_PII_SOCKET
6456 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6457#endif
6458#ifdef _SC_PII_XTI
6459 {"SC_PII_XTI", _SC_PII_XTI},
6460#endif
6461#ifdef _SC_POLL
6462 {"SC_POLL", _SC_POLL},
6463#endif
6464#ifdef _SC_PRIORITIZED_IO
6465 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6466#endif
6467#ifdef _SC_PRIORITY_SCHEDULING
6468 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6469#endif
6470#ifdef _SC_REALTIME_SIGNALS
6471 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6472#endif
6473#ifdef _SC_RE_DUP_MAX
6474 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6475#endif
6476#ifdef _SC_RTSIG_MAX
6477 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6478#endif
6479#ifdef _SC_SAVED_IDS
6480 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6481#endif
6482#ifdef _SC_SCHAR_MAX
6483 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6484#endif
6485#ifdef _SC_SCHAR_MIN
6486 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6487#endif
6488#ifdef _SC_SELECT
6489 {"SC_SELECT", _SC_SELECT},
6490#endif
6491#ifdef _SC_SEMAPHORES
6492 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6493#endif
6494#ifdef _SC_SEM_NSEMS_MAX
6495 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6496#endif
6497#ifdef _SC_SEM_VALUE_MAX
6498 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6499#endif
6500#ifdef _SC_SHARED_MEMORY_OBJECTS
6501 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6502#endif
6503#ifdef _SC_SHRT_MAX
6504 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6505#endif
6506#ifdef _SC_SHRT_MIN
6507 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6508#endif
6509#ifdef _SC_SIGQUEUE_MAX
6510 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6511#endif
6512#ifdef _SC_SIGRT_MAX
6513 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6514#endif
6515#ifdef _SC_SIGRT_MIN
6516 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6517#endif
Fred Draked86ed291999-12-15 15:34:33 +00006518#ifdef _SC_SOFTPOWER
6519 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6520#endif
Fred Drakec9680921999-12-13 16:37:25 +00006521#ifdef _SC_SPLIT_CACHE
6522 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6523#endif
6524#ifdef _SC_SSIZE_MAX
6525 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6526#endif
6527#ifdef _SC_STACK_PROT
6528 {"SC_STACK_PROT", _SC_STACK_PROT},
6529#endif
6530#ifdef _SC_STREAM_MAX
6531 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6532#endif
6533#ifdef _SC_SYNCHRONIZED_IO
6534 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6535#endif
6536#ifdef _SC_THREADS
6537 {"SC_THREADS", _SC_THREADS},
6538#endif
6539#ifdef _SC_THREAD_ATTR_STACKADDR
6540 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6541#endif
6542#ifdef _SC_THREAD_ATTR_STACKSIZE
6543 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6544#endif
6545#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6546 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6547#endif
6548#ifdef _SC_THREAD_KEYS_MAX
6549 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6550#endif
6551#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6552 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6553#endif
6554#ifdef _SC_THREAD_PRIO_INHERIT
6555 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6556#endif
6557#ifdef _SC_THREAD_PRIO_PROTECT
6558 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6559#endif
6560#ifdef _SC_THREAD_PROCESS_SHARED
6561 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6562#endif
6563#ifdef _SC_THREAD_SAFE_FUNCTIONS
6564 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6565#endif
6566#ifdef _SC_THREAD_STACK_MIN
6567 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6568#endif
6569#ifdef _SC_THREAD_THREADS_MAX
6570 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6571#endif
6572#ifdef _SC_TIMERS
6573 {"SC_TIMERS", _SC_TIMERS},
6574#endif
6575#ifdef _SC_TIMER_MAX
6576 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6577#endif
6578#ifdef _SC_TTY_NAME_MAX
6579 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6580#endif
6581#ifdef _SC_TZNAME_MAX
6582 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6583#endif
6584#ifdef _SC_T_IOV_MAX
6585 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6586#endif
6587#ifdef _SC_UCHAR_MAX
6588 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6589#endif
6590#ifdef _SC_UINT_MAX
6591 {"SC_UINT_MAX", _SC_UINT_MAX},
6592#endif
6593#ifdef _SC_UIO_MAXIOV
6594 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6595#endif
6596#ifdef _SC_ULONG_MAX
6597 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6598#endif
6599#ifdef _SC_USHRT_MAX
6600 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6601#endif
6602#ifdef _SC_VERSION
6603 {"SC_VERSION", _SC_VERSION},
6604#endif
6605#ifdef _SC_WORD_BIT
6606 {"SC_WORD_BIT", _SC_WORD_BIT},
6607#endif
6608#ifdef _SC_XBS5_ILP32_OFF32
6609 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6610#endif
6611#ifdef _SC_XBS5_ILP32_OFFBIG
6612 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6613#endif
6614#ifdef _SC_XBS5_LP64_OFF64
6615 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6616#endif
6617#ifdef _SC_XBS5_LPBIG_OFFBIG
6618 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6619#endif
6620#ifdef _SC_XOPEN_CRYPT
6621 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6622#endif
6623#ifdef _SC_XOPEN_ENH_I18N
6624 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6625#endif
6626#ifdef _SC_XOPEN_LEGACY
6627 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6628#endif
6629#ifdef _SC_XOPEN_REALTIME
6630 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6631#endif
6632#ifdef _SC_XOPEN_REALTIME_THREADS
6633 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6634#endif
6635#ifdef _SC_XOPEN_SHM
6636 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6637#endif
6638#ifdef _SC_XOPEN_UNIX
6639 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6640#endif
6641#ifdef _SC_XOPEN_VERSION
6642 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6643#endif
6644#ifdef _SC_XOPEN_XCU_VERSION
6645 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6646#endif
6647#ifdef _SC_XOPEN_XPG2
6648 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6649#endif
6650#ifdef _SC_XOPEN_XPG3
6651 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6652#endif
6653#ifdef _SC_XOPEN_XPG4
6654 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6655#endif
6656};
6657
6658static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006659conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006660{
6661 return conv_confname(arg, valuep, posix_constants_sysconf,
6662 sizeof(posix_constants_sysconf)
6663 / sizeof(struct constdef));
6664}
6665
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006666PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006667"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006668Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006669
6670static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006671posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006672{
6673 PyObject *result = NULL;
6674 int name;
6675
6676 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6677 int value;
6678
6679 errno = 0;
6680 value = sysconf(name);
6681 if (value == -1 && errno != 0)
6682 posix_error();
6683 else
Christian Heimes217cfd12007-12-02 14:31:20 +00006684 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00006685 }
6686 return result;
6687}
6688#endif
6689
6690
Fred Drakebec628d1999-12-15 18:31:10 +00006691/* This code is used to ensure that the tables of configuration value names
6692 * are in sorted order as required by conv_confname(), and also to build the
6693 * the exported dictionaries that are used to publish information about the
6694 * names available on the host platform.
6695 *
6696 * Sorting the table at runtime ensures that the table is properly ordered
6697 * when used, even for platforms we're not able to test on. It also makes
6698 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006699 */
Fred Drakebec628d1999-12-15 18:31:10 +00006700
6701static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006702cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006703{
6704 const struct constdef *c1 =
6705 (const struct constdef *) v1;
6706 const struct constdef *c2 =
6707 (const struct constdef *) v2;
6708
6709 return strcmp(c1->name, c2->name);
6710}
6711
6712static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006713setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006714 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006715{
Fred Drakebec628d1999-12-15 18:31:10 +00006716 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006717 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006718
6719 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6720 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006721 if (d == NULL)
6722 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006723
Barry Warsaw3155db32000-04-13 15:20:40 +00006724 for (i=0; i < tablesize; ++i) {
Christian Heimes217cfd12007-12-02 14:31:20 +00006725 PyObject *o = PyLong_FromLong(table[i].value);
Barry Warsaw3155db32000-04-13 15:20:40 +00006726 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6727 Py_XDECREF(o);
6728 Py_DECREF(d);
6729 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006730 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006731 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006732 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006733 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006734}
6735
Fred Drakebec628d1999-12-15 18:31:10 +00006736/* Return -1 on failure, 0 on success. */
6737static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006738setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006739{
6740#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006741 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006742 sizeof(posix_constants_pathconf)
6743 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006744 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006745 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006746#endif
6747#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006748 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006749 sizeof(posix_constants_confstr)
6750 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006751 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006752 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006753#endif
6754#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006755 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006756 sizeof(posix_constants_sysconf)
6757 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006758 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006759 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006760#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006761 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006762}
Fred Draked86ed291999-12-15 15:34:33 +00006763
6764
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006765PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006766"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006767Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006768in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006769
6770static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006771posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006772{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006773 abort();
6774 /*NOTREACHED*/
6775 Py_FatalError("abort() called from Python code didn't abort!");
6776 return NULL;
6777}
Fred Drakebec628d1999-12-15 18:31:10 +00006778
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006779#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006780PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00006781"startfile(filepath [, operation]) - Start a file with its associated\n\
6782application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006783\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00006784When \"operation\" is not specified or \"open\", this acts like\n\
6785double-clicking the file in Explorer, or giving the file name as an\n\
6786argument to the DOS \"start\" command: the file is opened with whatever\n\
6787application (if any) its extension is associated.\n\
6788When another \"operation\" is given, it specifies what should be done with\n\
6789the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006790\n\
6791startfile returns as soon as the associated application is launched.\n\
6792There is no option to wait for the application to close, and no way\n\
6793to retrieve the application's exit status.\n\
6794\n\
6795The filepath is relative to the current directory. If you want to use\n\
6796an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006797the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006798
6799static PyObject *
6800win32_startfile(PyObject *self, PyObject *args)
6801{
Martin v. Löwis011e8422009-05-05 04:43:17 +00006802 PyObject *ofilepath;
Tim Petersf58a7aa2000-09-22 10:05:54 +00006803 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00006804 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00006805 HINSTANCE rc;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006806#ifdef Py_WIN_WIDE_FILENAMES
6807 if (unicode_file_names()) {
6808 PyObject *unipath, *woperation = NULL;
6809 if (!PyArg_ParseTuple(args, "U|s:startfile",
6810 &unipath, &operation)) {
6811 PyErr_Clear();
6812 goto normal;
6813 }
6814
6815
6816 if (operation) {
6817 woperation = PyUnicode_DecodeASCII(operation,
6818 strlen(operation), NULL);
6819 if (!woperation) {
6820 PyErr_Clear();
6821 operation = NULL;
6822 goto normal;
6823 }
6824 }
6825
6826 Py_BEGIN_ALLOW_THREADS
6827 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
6828 PyUnicode_AS_UNICODE(unipath),
6829 NULL, NULL, SW_SHOWNORMAL);
6830 Py_END_ALLOW_THREADS
6831
6832 Py_XDECREF(woperation);
6833 if (rc <= (HINSTANCE)32) {
6834 PyObject *errval = win32_error_unicode("startfile",
6835 PyUnicode_AS_UNICODE(unipath));
6836 return errval;
6837 }
6838 Py_INCREF(Py_None);
6839 return Py_None;
6840 }
6841#endif
6842
6843normal:
Martin v. Löwis011e8422009-05-05 04:43:17 +00006844 if (!PyArg_ParseTuple(args, "O&|s:startfile",
6845 PyUnicode_FSConverter, &ofilepath,
Georg Brandlf4f44152006-02-18 22:29:33 +00006846 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00006847 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00006848 filepath = bytes2str(ofilepath, 1);
Tim Petersf58a7aa2000-09-22 10:05:54 +00006849 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00006850 rc = ShellExecute((HWND)0, operation, filepath,
6851 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00006852 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00006853 if (rc <= (HINSTANCE)32) {
6854 PyObject *errval = win32_error("startfile", filepath);
Martin v. Löwis011e8422009-05-05 04:43:17 +00006855 release_bytes(ofilepath);
Georg Brandle9f8ec92005-09-25 06:16:40 +00006856 return errval;
6857 }
Martin v. Löwis011e8422009-05-05 04:43:17 +00006858 release_bytes(ofilepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00006859 Py_INCREF(Py_None);
6860 return Py_None;
6861}
6862#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006863
Martin v. Löwis438b5342002-12-27 10:16:42 +00006864#ifdef HAVE_GETLOADAVG
6865PyDoc_STRVAR(posix_getloadavg__doc__,
6866"getloadavg() -> (float, float, float)\n\n\
6867Return the number of processes in the system run queue averaged over\n\
6868the last 1, 5, and 15 minutes or raises OSError if the load average\n\
6869was unobtainable");
6870
6871static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006872posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00006873{
6874 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00006875 if (getloadavg(loadavg, 3)!=3) {
6876 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
6877 return NULL;
6878 } else
6879 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
6880}
6881#endif
6882
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006883#ifdef MS_WINDOWS
6884
6885PyDoc_STRVAR(win32_urandom__doc__,
6886"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00006887Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006888
6889typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
6890 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
6891 DWORD dwFlags );
6892typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
6893 BYTE *pbBuffer );
6894
6895static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00006896/* This handle is never explicitly released. Instead, the operating
6897 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006898static HCRYPTPROV hCryptProv = 0;
6899
Tim Peters4ad82172004-08-30 17:02:04 +00006900static PyObject*
6901win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006902{
Tim Petersd3115382004-08-30 17:36:46 +00006903 int howMany;
6904 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006905
Tim Peters4ad82172004-08-30 17:02:04 +00006906 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00006907 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00006908 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00006909 if (howMany < 0)
6910 return PyErr_Format(PyExc_ValueError,
6911 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006912
Tim Peters4ad82172004-08-30 17:02:04 +00006913 if (hCryptProv == 0) {
6914 HINSTANCE hAdvAPI32 = NULL;
6915 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006916
Tim Peters4ad82172004-08-30 17:02:04 +00006917 /* Obtain handle to the DLL containing CryptoAPI
6918 This should not fail */
6919 hAdvAPI32 = GetModuleHandle("advapi32.dll");
6920 if(hAdvAPI32 == NULL)
6921 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006922
Tim Peters4ad82172004-08-30 17:02:04 +00006923 /* Obtain pointers to the CryptoAPI functions
6924 This will fail on some early versions of Win95 */
6925 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
6926 hAdvAPI32,
6927 "CryptAcquireContextA");
6928 if (pCryptAcquireContext == NULL)
6929 return PyErr_Format(PyExc_NotImplementedError,
6930 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006931
Tim Peters4ad82172004-08-30 17:02:04 +00006932 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
6933 hAdvAPI32, "CryptGenRandom");
Thomas Wouters89f507f2006-12-13 04:49:30 +00006934 if (pCryptGenRandom == NULL)
Tim Peters4ad82172004-08-30 17:02:04 +00006935 return PyErr_Format(PyExc_NotImplementedError,
6936 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006937
Tim Peters4ad82172004-08-30 17:02:04 +00006938 /* Acquire context */
6939 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
6940 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
6941 return win32_error("CryptAcquireContext", NULL);
6942 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006943
Tim Peters4ad82172004-08-30 17:02:04 +00006944 /* Allocate bytes */
Christian Heimes72b710a2008-05-26 13:28:38 +00006945 result = PyBytes_FromStringAndSize(NULL, howMany);
Tim Petersd3115382004-08-30 17:36:46 +00006946 if (result != NULL) {
6947 /* Get random data */
Amaury Forgeot d'Arca05ada32008-07-21 21:13:14 +00006948 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
Tim Petersd3115382004-08-30 17:36:46 +00006949 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
Christian Heimes72b710a2008-05-26 13:28:38 +00006950 PyBytes_AS_STRING(result))) {
Tim Petersd3115382004-08-30 17:36:46 +00006951 Py_DECREF(result);
6952 return win32_error("CryptGenRandom", NULL);
6953 }
Tim Peters4ad82172004-08-30 17:02:04 +00006954 }
Tim Petersd3115382004-08-30 17:36:46 +00006955 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006956}
6957#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00006958
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00006959PyDoc_STRVAR(device_encoding__doc__,
6960"device_encoding(fd) -> str\n\n\
6961Return a string describing the encoding of the device\n\
6962if the output is a terminal; else return None.");
6963
6964static PyObject *
6965device_encoding(PyObject *self, PyObject *args)
6966{
6967 int fd;
6968 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
6969 return NULL;
Kristján Valur Jónsson649170b2009-03-24 14:15:49 +00006970 if (!_PyVerify_fd(fd) || !isatty(fd)) {
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00006971 Py_INCREF(Py_None);
6972 return Py_None;
6973 }
6974#if defined(MS_WINDOWS) || defined(MS_WIN64)
6975 if (fd == 0) {
6976 char buf[100];
6977 sprintf(buf, "cp%d", GetConsoleCP());
6978 return PyUnicode_FromString(buf);
6979 }
6980 if (fd == 1 || fd == 2) {
6981 char buf[100];
6982 sprintf(buf, "cp%d", GetConsoleOutputCP());
6983 return PyUnicode_FromString(buf);
6984 }
6985#elif defined(CODESET)
6986 {
6987 char *codeset = nl_langinfo(CODESET);
Mark Dickinsonda2706b2008-12-11 18:03:03 +00006988 if (codeset != NULL && codeset[0] != 0)
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00006989 return PyUnicode_FromString(codeset);
6990 }
6991#endif
6992 Py_INCREF(Py_None);
6993 return Py_None;
6994}
6995
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006996#ifdef __VMS
6997/* Use openssl random routine */
6998#include <openssl/rand.h>
6999PyDoc_STRVAR(vms_urandom__doc__,
7000"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007001Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007002
7003static PyObject*
7004vms_urandom(PyObject *self, PyObject *args)
7005{
7006 int howMany;
7007 PyObject* result;
7008
7009 /* Read arguments */
7010 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7011 return NULL;
7012 if (howMany < 0)
7013 return PyErr_Format(PyExc_ValueError,
7014 "negative argument not allowed");
7015
7016 /* Allocate bytes */
Christian Heimes72b710a2008-05-26 13:28:38 +00007017 result = PyBytes_FromStringAndSize(NULL, howMany);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007018 if (result != NULL) {
7019 /* Get random data */
7020 if (RAND_pseudo_bytes((unsigned char*)
Christian Heimes72b710a2008-05-26 13:28:38 +00007021 PyBytes_AS_STRING(result),
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007022 howMany) < 0) {
7023 Py_DECREF(result);
7024 return PyErr_Format(PyExc_ValueError,
7025 "RAND_pseudo_bytes");
7026 }
7027 }
7028 return result;
7029}
7030#endif
7031
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007032static PyMethodDef posix_methods[] = {
7033 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7034#ifdef HAVE_TTYNAME
7035 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7036#endif
7037 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007038#ifdef HAVE_CHFLAGS
7039 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
7040#endif /* HAVE_CHFLAGS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007041 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007042#ifdef HAVE_FCHMOD
7043 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
7044#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007045#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007046 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007047#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +00007048#ifdef HAVE_LCHMOD
7049 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
7050#endif /* HAVE_LCHMOD */
7051#ifdef HAVE_FCHOWN
7052 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
7053#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00007054#ifdef HAVE_LCHFLAGS
7055 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
7056#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007057#ifdef HAVE_LCHOWN
7058 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7059#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007060#ifdef HAVE_CHROOT
7061 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7062#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007063#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007064 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007065#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007066#ifdef HAVE_GETCWD
Guido van Rossumf0af3e32008-10-02 18:55:37 +00007067 {"getcwd", (PyCFunction)posix_getcwd_unicode,
7068 METH_NOARGS, posix_getcwd__doc__},
7069 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
7070 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007071#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007072#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007073 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007074#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007075 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7076 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7077 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007078#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007079 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007080#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007081#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007082 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007083#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007084 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7085 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7086 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007087 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007088#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007089 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007090#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007091#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007092 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007093#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007094 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007095#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007096 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007097#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007098 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7099 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7100 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007101#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007102 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007103#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007104 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007105#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007106 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7107 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007108#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007109#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007110 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7111 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007112#if defined(PYOS_OS2)
7113 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7114 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
7115#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007116#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007117#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00007118 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007119#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007120#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00007121 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007122#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007123#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00007124 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007125#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007126#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00007127 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007128#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007129#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007130 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007131#endif /* HAVE_GETEGID */
7132#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007133 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007134#endif /* HAVE_GETEUID */
7135#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007136 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007137#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007138#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007139 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007140#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007141 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007142#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007143 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007144#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007145#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007146 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007147#endif /* HAVE_GETPPID */
7148#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007149 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007150#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007151#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007152 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007153#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007154#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007155 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007156#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007157#ifdef HAVE_KILLPG
7158 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7159#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007160#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007161 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007162#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +00007163#ifdef MS_WINDOWS
7164 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
7165#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007166#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007167 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007168#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007169#ifdef HAVE_SETEUID
7170 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7171#endif /* HAVE_SETEUID */
7172#ifdef HAVE_SETEGID
7173 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7174#endif /* HAVE_SETEGID */
7175#ifdef HAVE_SETREUID
7176 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7177#endif /* HAVE_SETREUID */
7178#ifdef HAVE_SETREGID
7179 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7180#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007181#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007182 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007183#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007184#ifdef HAVE_SETGROUPS
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00007185 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007186#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007187#ifdef HAVE_GETPGID
7188 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7189#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007190#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007191 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007192#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007193#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007194 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007195#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007196#ifdef HAVE_WAIT3
7197 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
7198#endif /* HAVE_WAIT3 */
7199#ifdef HAVE_WAIT4
7200 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
7201#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00007202#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007203 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007204#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007205#ifdef HAVE_GETSID
7206 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
7207#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007208#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007209 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007210#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007211#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007212 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007213#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007214#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007215 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007216#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007217#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007218 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007219#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007220 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7221 {"close", posix_close, METH_VARARGS, posix_close__doc__},
Christian Heimesfdab48e2008-01-20 09:06:41 +00007222 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007223 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007224 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7225 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7226 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7227 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7228 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7229 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007230 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007231#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007232 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007233#endif
7234#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007235 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007236#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007237#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007238 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7239#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007240#ifdef HAVE_DEVICE_MACROS
7241 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7242 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7243 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7244#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007245#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007246 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007247#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007248#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007249 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007250#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007251#ifdef HAVE_UNSETENV
7252 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7253#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007254 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007255#ifdef HAVE_FCHDIR
7256 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7257#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007258#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007259 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007260#endif
7261#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007262 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007263#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007264#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007265#ifdef WCOREDUMP
7266 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7267#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007268#ifdef WIFCONTINUED
7269 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7270#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007271#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007272 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007273#endif /* WIFSTOPPED */
7274#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007275 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007276#endif /* WIFSIGNALED */
7277#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007278 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007279#endif /* WIFEXITED */
7280#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007281 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007282#endif /* WEXITSTATUS */
7283#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007284 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007285#endif /* WTERMSIG */
7286#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007287 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007288#endif /* WSTOPSIG */
7289#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00007290#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007291 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007292#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00007293#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007294 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007295#endif
Fred Drakec9680921999-12-13 16:37:25 +00007296#ifdef HAVE_CONFSTR
7297 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7298#endif
7299#ifdef HAVE_SYSCONF
7300 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7301#endif
7302#ifdef HAVE_FPATHCONF
7303 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7304#endif
7305#ifdef HAVE_PATHCONF
7306 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7307#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007308 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007309#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007310 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7311#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007312#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007313 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007314#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007315 #ifdef MS_WINDOWS
7316 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
7317 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007318 #ifdef __VMS
7319 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
7320 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007321 {NULL, NULL} /* Sentinel */
7322};
7323
7324
Barry Warsaw4a342091996-12-19 23:50:02 +00007325static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007326ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007327{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007328 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007329}
7330
Guido van Rossumd48f2521997-12-05 22:19:34 +00007331#if defined(PYOS_OS2)
7332/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007333static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007334{
7335 APIRET rc;
7336 ULONG values[QSV_MAX+1];
7337 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007338 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007339
7340 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007341 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007342 Py_END_ALLOW_THREADS
7343
7344 if (rc != NO_ERROR) {
7345 os2_error(rc);
7346 return -1;
7347 }
7348
Fred Drake4d1e64b2002-04-15 19:40:07 +00007349 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7350 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7351 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7352 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7353 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7354 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7355 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007356
7357 switch (values[QSV_VERSION_MINOR]) {
7358 case 0: ver = "2.00"; break;
7359 case 10: ver = "2.10"; break;
7360 case 11: ver = "2.11"; break;
7361 case 30: ver = "3.00"; break;
7362 case 40: ver = "4.00"; break;
7363 case 50: ver = "5.00"; break;
7364 default:
Tim Peters885d4572001-11-28 20:27:42 +00007365 PyOS_snprintf(tmp, sizeof(tmp),
7366 "%d-%d", values[QSV_VERSION_MAJOR],
7367 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007368 ver = &tmp[0];
7369 }
7370
7371 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007372 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007373 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007374
7375 /* Add Indicator of Which Drive was Used to Boot the System */
7376 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7377 tmp[1] = ':';
7378 tmp[2] = '\0';
7379
Fred Drake4d1e64b2002-04-15 19:40:07 +00007380 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007381}
7382#endif
7383
Barry Warsaw4a342091996-12-19 23:50:02 +00007384static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007385all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007386{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007387#ifdef F_OK
7388 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007389#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007390#ifdef R_OK
7391 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007392#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007393#ifdef W_OK
7394 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007395#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007396#ifdef X_OK
7397 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007398#endif
Fred Drakec9680921999-12-13 16:37:25 +00007399#ifdef NGROUPS_MAX
7400 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7401#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007402#ifdef TMP_MAX
7403 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7404#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007405#ifdef WCONTINUED
7406 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7407#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007408#ifdef WNOHANG
7409 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007410#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007411#ifdef WUNTRACED
7412 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7413#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007414#ifdef O_RDONLY
7415 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7416#endif
7417#ifdef O_WRONLY
7418 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7419#endif
7420#ifdef O_RDWR
7421 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7422#endif
7423#ifdef O_NDELAY
7424 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7425#endif
7426#ifdef O_NONBLOCK
7427 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7428#endif
7429#ifdef O_APPEND
7430 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7431#endif
7432#ifdef O_DSYNC
7433 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7434#endif
7435#ifdef O_RSYNC
7436 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7437#endif
7438#ifdef O_SYNC
7439 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7440#endif
7441#ifdef O_NOCTTY
7442 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7443#endif
7444#ifdef O_CREAT
7445 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7446#endif
7447#ifdef O_EXCL
7448 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7449#endif
7450#ifdef O_TRUNC
7451 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7452#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007453#ifdef O_BINARY
7454 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7455#endif
7456#ifdef O_TEXT
7457 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7458#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007459#ifdef O_LARGEFILE
7460 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7461#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00007462#ifdef O_SHLOCK
7463 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
7464#endif
7465#ifdef O_EXLOCK
7466 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
7467#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007468
Tim Peters5aa91602002-01-30 05:46:57 +00007469/* MS Windows */
7470#ifdef O_NOINHERIT
7471 /* Don't inherit in child processes. */
7472 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7473#endif
7474#ifdef _O_SHORT_LIVED
7475 /* Optimize for short life (keep in memory). */
7476 /* MS forgot to define this one with a non-underscore form too. */
7477 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7478#endif
7479#ifdef O_TEMPORARY
7480 /* Automatically delete when last handle is closed. */
7481 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7482#endif
7483#ifdef O_RANDOM
7484 /* Optimize for random access. */
7485 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7486#endif
7487#ifdef O_SEQUENTIAL
7488 /* Optimize for sequential access. */
7489 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7490#endif
7491
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007492/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +00007493#ifdef O_ASYNC
7494 /* Send a SIGIO signal whenever input or output
7495 becomes available on file descriptor */
7496 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
7497#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007498#ifdef O_DIRECT
7499 /* Direct disk access. */
7500 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7501#endif
7502#ifdef O_DIRECTORY
7503 /* Must be a directory. */
7504 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7505#endif
7506#ifdef O_NOFOLLOW
7507 /* Do not follow links. */
7508 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7509#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00007510#ifdef O_NOATIME
7511 /* Do not update the access time. */
7512 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
7513#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007514
Barry Warsaw5676bd12003-01-07 20:57:09 +00007515 /* These come from sysexits.h */
7516#ifdef EX_OK
7517 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007518#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007519#ifdef EX_USAGE
7520 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007521#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007522#ifdef EX_DATAERR
7523 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007524#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007525#ifdef EX_NOINPUT
7526 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007527#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007528#ifdef EX_NOUSER
7529 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007530#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007531#ifdef EX_NOHOST
7532 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007533#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007534#ifdef EX_UNAVAILABLE
7535 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007536#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007537#ifdef EX_SOFTWARE
7538 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007539#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007540#ifdef EX_OSERR
7541 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007542#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007543#ifdef EX_OSFILE
7544 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007545#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007546#ifdef EX_CANTCREAT
7547 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007548#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007549#ifdef EX_IOERR
7550 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007551#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007552#ifdef EX_TEMPFAIL
7553 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007554#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007555#ifdef EX_PROTOCOL
7556 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007557#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007558#ifdef EX_NOPERM
7559 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007560#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007561#ifdef EX_CONFIG
7562 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007563#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007564#ifdef EX_NOTFOUND
7565 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007566#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007567
Guido van Rossum246bc171999-02-01 23:54:31 +00007568#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007569#if defined(PYOS_OS2) && defined(PYCC_GCC)
7570 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7571 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7572 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7573 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7574 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7575 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7576 if (ins(d, "P_PM", (long)P_PM)) return -1;
7577 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7578 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7579 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7580 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7581 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7582 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7583 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7584 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7585 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7586 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7587 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7588 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7589 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7590#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007591 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7592 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7593 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7594 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7595 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007596#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007597#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007598
Guido van Rossumd48f2521997-12-05 22:19:34 +00007599#if defined(PYOS_OS2)
7600 if (insertvalues(d)) return -1;
7601#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007602 return 0;
7603}
7604
7605
Tim Peters5aa91602002-01-30 05:46:57 +00007606#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007607#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007608#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007609
7610#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007611#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007612#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007613
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007614#else
Martin v. Löwis1a214512008-06-11 05:26:20 +00007615#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007616#define MODNAME "posix"
7617#endif
7618
Martin v. Löwis1a214512008-06-11 05:26:20 +00007619static struct PyModuleDef posixmodule = {
7620 PyModuleDef_HEAD_INIT,
7621 MODNAME,
7622 posix__doc__,
7623 -1,
7624 posix_methods,
7625 NULL,
7626 NULL,
7627 NULL,
7628 NULL
7629};
7630
7631
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007632PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007633INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007634{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007635 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007636
Martin v. Löwis1a214512008-06-11 05:26:20 +00007637 m = PyModule_Create(&posixmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00007638 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007639 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007640
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007641 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007642 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007643 Py_XINCREF(v);
7644 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007645 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00007646 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007647
Fred Drake4d1e64b2002-04-15 19:40:07 +00007648 if (all_ins(m))
Martin v. Löwis1a214512008-06-11 05:26:20 +00007649 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +00007650
Fred Drake4d1e64b2002-04-15 19:40:07 +00007651 if (setup_confname_tables(m))
Martin v. Löwis1a214512008-06-11 05:26:20 +00007652 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +00007653
Fred Drake4d1e64b2002-04-15 19:40:07 +00007654 Py_INCREF(PyExc_OSError);
7655 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007656
Guido van Rossumb3d39562000-01-31 18:41:26 +00007657#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007658 if (posix_putenv_garbage == NULL)
7659 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007660#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007661
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007662 if (!initialized) {
7663 stat_result_desc.name = MODNAME ".stat_result";
7664 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7665 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7666 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
7667 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
7668 structseq_new = StatResultType.tp_new;
7669 StatResultType.tp_new = statresult_new;
7670
7671 statvfs_result_desc.name = MODNAME ".statvfs_result";
7672 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00007673#ifdef NEED_TICKS_PER_SECOND
7674# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
7675 ticks_per_second = sysconf(_SC_CLK_TCK);
7676# elif defined(HZ)
7677 ticks_per_second = HZ;
7678# else
7679 ticks_per_second = 60; /* magic fallback value; may be bogus */
7680# endif
7681#endif
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007682 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007683 Py_INCREF((PyObject*) &StatResultType);
7684 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007685 Py_INCREF((PyObject*) &StatVFSResultType);
7686 PyModule_AddObject(m, "statvfs_result",
7687 (PyObject*) &StatVFSResultType);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007688 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007689
7690#ifdef __APPLE__
7691 /*
7692 * Step 2 of weak-linking support on Mac OS X.
7693 *
7694 * The code below removes functions that are not available on the
7695 * currently active platform.
7696 *
7697 * This block allow one to use a python binary that was build on
7698 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
7699 * OSX 10.4.
7700 */
7701#ifdef HAVE_FSTATVFS
7702 if (fstatvfs == NULL) {
7703 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
Martin v. Löwis1a214512008-06-11 05:26:20 +00007704 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007705 }
7706 }
7707#endif /* HAVE_FSTATVFS */
7708
7709#ifdef HAVE_STATVFS
7710 if (statvfs == NULL) {
7711 if (PyObject_DelAttrString(m, "statvfs") == -1) {
Martin v. Löwis1a214512008-06-11 05:26:20 +00007712 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007713 }
7714 }
7715#endif /* HAVE_STATVFS */
7716
7717# ifdef HAVE_LCHOWN
7718 if (lchown == NULL) {
7719 if (PyObject_DelAttrString(m, "lchown") == -1) {
Martin v. Löwis1a214512008-06-11 05:26:20 +00007720 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007721 }
7722 }
7723#endif /* HAVE_LCHOWN */
7724
7725
7726#endif /* __APPLE__ */
Martin v. Löwis1a214512008-06-11 05:26:20 +00007727 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007728
Guido van Rossumb6775db1994-08-01 11:34:53 +00007729}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007730
7731#ifdef __cplusplus
7732}
7733#endif