blob: 658d159c4a30769a855c4a7892aede9ccecfe01d [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
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000189extern int chown(const char *, uid_t, gid_t);
190extern char *getcwd(char *, int);
191extern char *strerror(int);
192extern int link(const char *, const char *);
193extern int rename(const char *, const char *);
194extern int stat(const char *, struct stat *);
195extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000196#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000197extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000198#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000199#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000200extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000201#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000202#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000203
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000204#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000205
Guido van Rossumb6775db1994-08-01 11:34:53 +0000206#ifdef HAVE_UTIME_H
207#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000208#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000209
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000210#ifdef HAVE_SYS_UTIME_H
211#include <sys/utime.h>
212#define HAVE_UTIME_H /* pretend we do for the rest of this file */
213#endif /* HAVE_SYS_UTIME_H */
214
Guido van Rossumb6775db1994-08-01 11:34:53 +0000215#ifdef HAVE_SYS_TIMES_H
216#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000217#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000218
219#ifdef HAVE_SYS_PARAM_H
220#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000221#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000222
223#ifdef HAVE_SYS_UTSNAME_H
224#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000225#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000227#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000228#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000229#define NAMLEN(dirent) strlen((dirent)->d_name)
230#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000231#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000232#include <direct.h>
233#define NAMLEN(dirent) strlen((dirent)->d_name)
234#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000236#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000237#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000238#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000239#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000240#endif
241#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000242#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000243#endif
244#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000246#endif
247#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000248
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000249#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000250#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000252#endif
253#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000255#endif
256#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000258#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000259#include "osdefs.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000261#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000262#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263
Guido van Rossumd48f2521997-12-05 22:19:34 +0000264#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000265#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000266#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000267
Tim Petersbc2e10e2002-03-03 23:17:02 +0000268#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000269#if defined(PATH_MAX) && PATH_MAX > 1024
270#define MAXPATHLEN PATH_MAX
271#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000272#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000273#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000274#endif /* MAXPATHLEN */
275
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000276#ifdef UNION_WAIT
277/* Emulate some macros on systems that have a union instead of macros */
278
279#ifndef WIFEXITED
280#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
281#endif
282
283#ifndef WEXITSTATUS
284#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
285#endif
286
287#ifndef WTERMSIG
288#define WTERMSIG(u_wait) ((u_wait).w_termsig)
289#endif
290
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000291#define WAIT_TYPE union wait
292#define WAIT_STATUS_INT(s) (s.w_status)
293
294#else /* !UNION_WAIT */
295#define WAIT_TYPE int
296#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000297#endif /* UNION_WAIT */
298
Greg Wardb48bc172000-03-01 21:51:56 +0000299/* Don't use the "_r" form if we don't need it (also, won't have a
300 prototype for it, at least on Solaris -- maybe others as well?). */
301#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
302#define USE_CTERMID_R
303#endif
304
Fred Drake699f3522000-06-29 21:12:41 +0000305/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000306#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000307#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwis14694662006-02-03 12:54:16 +0000308# define STAT win32_stat
309# define FSTAT win32_fstat
310# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000311#else
312# define STAT stat
313# define FSTAT fstat
314# define STRUCT_STAT struct stat
315#endif
316
Tim Peters11b23062003-04-23 02:39:17 +0000317#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000318#include <sys/mkdev.h>
319#else
320#if defined(MAJOR_IN_SYSMACROS)
321#include <sys/sysmacros.h>
322#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000323#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
324#include <sys/mkdev.h>
325#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000326#endif
Fred Drake699f3522000-06-29 21:12:41 +0000327
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000328/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000329#ifdef WITH_NEXT_FRAMEWORK
330/* On Darwin/MacOSX a shared library or framework has no access to
331** environ directly, we must obtain it with _NSGetEnviron().
332*/
333#include <crt_externs.h>
334static char **environ;
335#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000336extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000337#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000338
Barry Warsaw53699e91996-12-10 23:23:01 +0000339static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000340convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000341{
Barry Warsaw53699e91996-12-10 23:23:01 +0000342 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000343#ifdef MS_WINDOWS
344 wchar_t **e;
345#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000346 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000347#endif
Barry Warsaw53699e91996-12-10 23:23:01 +0000348 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000349 if (d == NULL)
350 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000351#ifdef WITH_NEXT_FRAMEWORK
352 if (environ == NULL)
353 environ = *_NSGetEnviron();
354#endif
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000355#ifdef MS_WINDOWS
356 /* _wenviron must be initialized in this way if the program is started
357 through main() instead of wmain(). */
358 _wgetenv(L"");
359 if (_wenviron == NULL)
360 return d;
361 /* This part ignores errors */
362 for (e = _wenviron; *e != NULL; e++) {
363 PyObject *k;
364 PyObject *v;
365 wchar_t *p = wcschr(*e, L'=');
366 if (p == NULL)
367 continue;
368 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
369 if (k == NULL) {
370 PyErr_Clear();
371 continue;
372 }
373 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
374 if (v == NULL) {
375 PyErr_Clear();
376 Py_DECREF(k);
377 continue;
378 }
379 if (PyDict_GetItem(d, k) == NULL) {
380 if (PyDict_SetItem(d, k, v) != 0)
381 PyErr_Clear();
382 }
383 Py_DECREF(k);
384 Py_DECREF(v);
385 }
386#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000387 if (environ == NULL)
388 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000389 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000390 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000391 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000392 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000393 char *p = strchr(*e, '=');
394 if (p == NULL)
395 continue;
Guido van Rossum98297ee2007-11-06 21:34:58 +0000396 k = PyUnicode_FromStringAndSize(*e, (int)(p-*e));
Guido van Rossum6a619f41999-08-03 19:41:10 +0000397 if (k == NULL) {
398 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000399 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000400 }
Guido van Rossum98297ee2007-11-06 21:34:58 +0000401 v = PyUnicode_FromString(p+1);
Guido van Rossum6a619f41999-08-03 19:41:10 +0000402 if (v == NULL) {
403 PyErr_Clear();
404 Py_DECREF(k);
405 continue;
406 }
407 if (PyDict_GetItem(d, k) == NULL) {
408 if (PyDict_SetItem(d, k, v) != 0)
409 PyErr_Clear();
410 }
411 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000412 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000413 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000414#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000415#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000416 {
417 APIRET rc;
418 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
419
420 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000421 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000422 PyObject *v = PyString_FromString(buffer);
Neal Norwitz93c56822007-08-26 07:10:06 +0000423 PyDict_SetItemString(d, "BEGINLIBPATH", v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000424 Py_DECREF(v);
425 }
426 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
427 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
428 PyObject *v = PyString_FromString(buffer);
Neal Norwitz93c56822007-08-26 07:10:06 +0000429 PyDict_SetItemString(d, "ENDLIBPATH", v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000430 Py_DECREF(v);
431 }
432 }
433#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000434 return d;
435}
436
437
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000438/* Set a POSIX-specific error from errno, and return NULL */
439
Barry Warsawd58d7641998-07-23 16:14:40 +0000440static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000441posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000442{
Barry Warsawca74da41999-02-09 19:31:45 +0000443 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000444}
Barry Warsawd58d7641998-07-23 16:14:40 +0000445static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000446posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000447{
Barry Warsawca74da41999-02-09 19:31:45 +0000448 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000449}
450
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000451#ifdef Py_WIN_WIDE_FILENAMES
452static PyObject *
453posix_error_with_unicode_filename(Py_UNICODE* name)
454{
455 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
456}
457#endif /* Py_WIN_WIDE_FILENAMES */
458
459
Mark Hammondef8b6542001-05-13 08:04:26 +0000460static PyObject *
461posix_error_with_allocated_filename(char* name)
462{
463 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
464 PyMem_Free(name);
465 return rc;
466}
467
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000468#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000469static PyObject *
470win32_error(char* function, char* filename)
471{
Mark Hammond33a6da92000-08-15 00:46:38 +0000472 /* XXX We should pass the function name along in the future.
473 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000474 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000475 Windows error object, which is non-trivial.
476 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000477 errno = GetLastError();
478 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000479 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000480 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000481 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000482}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000483
484#ifdef Py_WIN_WIDE_FILENAMES
485static PyObject *
486win32_error_unicode(char* function, Py_UNICODE* filename)
487{
488 /* XXX - see win32_error for comments on 'function' */
489 errno = GetLastError();
490 if (filename)
491 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
492 else
493 return PyErr_SetFromWindowsErr(errno);
494}
495
496static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
497{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000498}
499
500/* Function suitable for O& conversion */
501static int
502convert_to_unicode(PyObject *arg, void* _param)
503{
504 PyObject **param = (PyObject**)_param;
505 if (PyUnicode_CheckExact(arg)) {
506 Py_INCREF(arg);
507 *param = arg;
508 }
509 else if (PyUnicode_Check(arg)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000510 /* For a Unicode subtype that's not a Unicode object,
511 return a true Unicode object with the same data. */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000512 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(arg),
513 PyUnicode_GET_SIZE(arg));
514 return *param != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000515 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000516 else
517 *param = PyUnicode_FromEncodedObject(arg,
518 Py_FileSystemDefaultEncoding,
519 "strict");
520 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000521}
522
523#endif /* Py_WIN_WIDE_FILENAMES */
524
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000525#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000526
Guido van Rossumd48f2521997-12-05 22:19:34 +0000527#if defined(PYOS_OS2)
528/**********************************************************************
529 * Helper Function to Trim and Format OS/2 Messages
530 **********************************************************************/
531 static void
532os2_formatmsg(char *msgbuf, int msglen, char *reason)
533{
534 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
535
536 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
537 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
538
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000539 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000540 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
541 }
542
543 /* Add Optional Reason Text */
544 if (reason) {
545 strcat(msgbuf, " : ");
546 strcat(msgbuf, reason);
547 }
548}
549
550/**********************************************************************
551 * Decode an OS/2 Operating System Error Code
552 *
553 * A convenience function to lookup an OS/2 error code and return a
554 * text message we can use to raise a Python exception.
555 *
556 * Notes:
557 * The messages for errors returned from the OS/2 kernel reside in
558 * the file OSO001.MSG in the \OS2 directory hierarchy.
559 *
560 **********************************************************************/
561 static char *
562os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
563{
564 APIRET rc;
565 ULONG msglen;
566
567 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
568 Py_BEGIN_ALLOW_THREADS
569 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
570 errorcode, "oso001.msg", &msglen);
571 Py_END_ALLOW_THREADS
572
573 if (rc == NO_ERROR)
574 os2_formatmsg(msgbuf, msglen, reason);
575 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000576 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000577 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000578
579 return msgbuf;
580}
581
582/* Set an OS/2-specific error and return NULL. OS/2 kernel
583 errors are not in a global variable e.g. 'errno' nor are
584 they congruent with posix error numbers. */
585
586static PyObject * os2_error(int code)
587{
588 char text[1024];
589 PyObject *v;
590
591 os2_strerror(text, sizeof(text), code, "");
592
593 v = Py_BuildValue("(is)", code, text);
594 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000595 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000596 Py_DECREF(v);
597 }
598 return NULL; /* Signal to Python that an Exception is Pending */
599}
600
601#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000602
603/* POSIX generic methods */
604
Barry Warsaw53699e91996-12-10 23:23:01 +0000605static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000606posix_fildes(PyObject *fdobj, int (*func)(int))
607{
608 int fd;
609 int res;
610 fd = PyObject_AsFileDescriptor(fdobj);
611 if (fd < 0)
612 return NULL;
613 Py_BEGIN_ALLOW_THREADS
614 res = (*func)(fd);
615 Py_END_ALLOW_THREADS
616 if (res < 0)
617 return posix_error();
618 Py_INCREF(Py_None);
619 return Py_None;
620}
Guido van Rossum21142a01999-01-08 21:05:37 +0000621
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000622#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000623static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000624unicode_file_names(void)
625{
626 static int canusewide = -1;
627 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000628 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000629 the Windows NT family. */
630 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
631 }
632 return canusewide;
633}
634#endif
Tim Peters11b23062003-04-23 02:39:17 +0000635
Guido van Rossum21142a01999-01-08 21:05:37 +0000636static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000637posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000638{
Mark Hammondef8b6542001-05-13 08:04:26 +0000639 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000640 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000641 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000642 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000643 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000644 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000645 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000646 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000647 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000648 return posix_error_with_allocated_filename(path1);
649 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000650 Py_INCREF(Py_None);
651 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000652}
653
Barry Warsaw53699e91996-12-10 23:23:01 +0000654static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000655posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000656 char *format,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000657 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000658{
Mark Hammondef8b6542001-05-13 08:04:26 +0000659 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000660 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000661 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000662 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000663 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000664 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000665 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000666 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000667 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000668 PyMem_Free(path1);
669 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000670 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000671 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000672 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000673 Py_INCREF(Py_None);
674 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000675}
676
Thomas Wouters477c8d52006-05-27 19:21:47 +0000677#ifdef Py_WIN_WIDE_FILENAMES
678static PyObject*
679win32_1str(PyObject* args, char* func,
680 char* format, BOOL (__stdcall *funcA)(LPCSTR),
681 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
682{
683 PyObject *uni;
684 char *ansi;
685 BOOL result;
686 if (unicode_file_names()) {
687 if (!PyArg_ParseTuple(args, wformat, &uni))
688 PyErr_Clear();
689 else {
690 Py_BEGIN_ALLOW_THREADS
691 result = funcW(PyUnicode_AsUnicode(uni));
692 Py_END_ALLOW_THREADS
693 if (!result)
694 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
695 Py_INCREF(Py_None);
696 return Py_None;
697 }
698 }
699 if (!PyArg_ParseTuple(args, format, &ansi))
700 return NULL;
701 Py_BEGIN_ALLOW_THREADS
702 result = funcA(ansi);
703 Py_END_ALLOW_THREADS
704 if (!result)
705 return win32_error(func, ansi);
706 Py_INCREF(Py_None);
707 return Py_None;
708
709}
710
711/* This is a reimplementation of the C library's chdir function,
712 but one that produces Win32 errors instead of DOS error codes.
713 chdir is essentially a wrapper around SetCurrentDirectory; however,
714 it also needs to set "magic" environment variables indicating
715 the per-drive current directory, which are of the form =<drive>: */
716BOOL __stdcall
717win32_chdir(LPCSTR path)
718{
719 char new_path[MAX_PATH+1];
720 int result;
721 char env[4] = "=x:";
722
723 if(!SetCurrentDirectoryA(path))
724 return FALSE;
725 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
726 if (!result)
727 return FALSE;
728 /* In the ANSI API, there should not be any paths longer
729 than MAX_PATH. */
730 assert(result <= MAX_PATH+1);
731 if (strncmp(new_path, "\\\\", 2) == 0 ||
732 strncmp(new_path, "//", 2) == 0)
733 /* UNC path, nothing to do. */
734 return TRUE;
735 env[1] = new_path[0];
736 return SetEnvironmentVariableA(env, new_path);
737}
738
739/* The Unicode version differs from the ANSI version
740 since the current directory might exceed MAX_PATH characters */
741BOOL __stdcall
742win32_wchdir(LPCWSTR path)
743{
744 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
745 int result;
746 wchar_t env[4] = L"=x:";
747
748 if(!SetCurrentDirectoryW(path))
749 return FALSE;
750 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
751 if (!result)
752 return FALSE;
753 if (result > MAX_PATH+1) {
754 new_path = malloc(result);
755 if (!new_path) {
756 SetLastError(ERROR_OUTOFMEMORY);
757 return FALSE;
758 }
759 }
760 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
761 wcsncmp(new_path, L"//", 2) == 0)
762 /* UNC path, nothing to do. */
763 return TRUE;
764 env[1] = new_path[0];
765 result = SetEnvironmentVariableW(env, new_path);
766 if (new_path != _new_path)
767 free(new_path);
768 return result;
769}
770#endif
771
Martin v. Löwis14694662006-02-03 12:54:16 +0000772#ifdef MS_WINDOWS
773/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
774 - time stamps are restricted to second resolution
775 - file modification times suffer from forth-and-back conversions between
776 UTC and local time
777 Therefore, we implement our own stat, based on the Win32 API directly.
778*/
779#define HAVE_STAT_NSEC 1
780
781struct win32_stat{
782 int st_dev;
783 __int64 st_ino;
784 unsigned short st_mode;
785 int st_nlink;
786 int st_uid;
787 int st_gid;
788 int st_rdev;
789 __int64 st_size;
790 int st_atime;
791 int st_atime_nsec;
792 int st_mtime;
793 int st_mtime_nsec;
794 int st_ctime;
795 int st_ctime_nsec;
796};
797
798static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
799
800static void
801FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
802{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000803 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
804 /* Cannot simply cast and dereference in_ptr,
805 since it might not be aligned properly */
806 __int64 in;
807 memcpy(&in, in_ptr, sizeof(in));
Martin v. Löwis14694662006-02-03 12:54:16 +0000808 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
809 /* XXX Win32 supports time stamps past 2038; we currently don't */
810 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
811}
812
Thomas Wouters477c8d52006-05-27 19:21:47 +0000813static void
814time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
815{
816 /* XXX endianness */
817 __int64 out;
818 out = time_in + secs_between_epochs;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000819 out = out * 10000000 + nsec_in / 100;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000820 memcpy(out_ptr, &out, sizeof(out));
821}
822
Martin v. Löwis14694662006-02-03 12:54:16 +0000823/* Below, we *know* that ugo+r is 0444 */
824#if _S_IREAD != 0400
825#error Unsupported C library
826#endif
827static int
828attributes_to_mode(DWORD attr)
829{
830 int m = 0;
831 if (attr & FILE_ATTRIBUTE_DIRECTORY)
832 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
833 else
834 m |= _S_IFREG;
835 if (attr & FILE_ATTRIBUTE_READONLY)
836 m |= 0444;
837 else
838 m |= 0666;
839 return m;
840}
841
842static int
843attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
844{
845 memset(result, 0, sizeof(*result));
846 result->st_mode = attributes_to_mode(info->dwFileAttributes);
847 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
848 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
849 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
850 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
851
852 return 0;
853}
854
Thomas Wouters89f507f2006-12-13 04:49:30 +0000855/* Emulate GetFileAttributesEx[AW] on Windows 95 */
856static int checked = 0;
857static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
858static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
859static void
860check_gfax()
861{
862 HINSTANCE hKernel32;
863 if (checked)
864 return;
865 checked = 1;
866 hKernel32 = GetModuleHandle("KERNEL32");
867 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
868 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
869}
870
Guido van Rossumd8faa362007-04-27 19:54:29 +0000871static BOOL
872attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
873{
874 HANDLE hFindFile;
875 WIN32_FIND_DATAA FileData;
876 hFindFile = FindFirstFileA(pszFile, &FileData);
877 if (hFindFile == INVALID_HANDLE_VALUE)
878 return FALSE;
879 FindClose(hFindFile);
880 pfad->dwFileAttributes = FileData.dwFileAttributes;
881 pfad->ftCreationTime = FileData.ftCreationTime;
882 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
883 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
884 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
885 pfad->nFileSizeLow = FileData.nFileSizeLow;
886 return TRUE;
887}
888
889static BOOL
890attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
891{
892 HANDLE hFindFile;
893 WIN32_FIND_DATAW FileData;
894 hFindFile = FindFirstFileW(pszFile, &FileData);
895 if (hFindFile == INVALID_HANDLE_VALUE)
896 return FALSE;
897 FindClose(hFindFile);
898 pfad->dwFileAttributes = FileData.dwFileAttributes;
899 pfad->ftCreationTime = FileData.ftCreationTime;
900 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
901 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
902 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
903 pfad->nFileSizeLow = FileData.nFileSizeLow;
904 return TRUE;
905}
906
Thomas Wouters89f507f2006-12-13 04:49:30 +0000907static BOOL WINAPI
908Py_GetFileAttributesExA(LPCSTR pszFile,
909 GET_FILEEX_INFO_LEVELS level,
910 LPVOID pv)
911{
912 BOOL result;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000913 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
914 /* First try to use the system's implementation, if that is
915 available and either succeeds to gives an error other than
916 that it isn't implemented. */
917 check_gfax();
918 if (gfaxa) {
919 result = gfaxa(pszFile, level, pv);
920 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
921 return result;
922 }
923 /* It's either not present, or not implemented.
924 Emulate using FindFirstFile. */
925 if (level != GetFileExInfoStandard) {
926 SetLastError(ERROR_INVALID_PARAMETER);
927 return FALSE;
928 }
929 /* Use GetFileAttributes to validate that the file name
930 does not contain wildcards (which FindFirstFile would
931 accept). */
932 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
933 return FALSE;
Guido van Rossumd8faa362007-04-27 19:54:29 +0000934 return attributes_from_dir(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +0000935}
936
937static BOOL WINAPI
938Py_GetFileAttributesExW(LPCWSTR pszFile,
939 GET_FILEEX_INFO_LEVELS level,
940 LPVOID pv)
941{
942 BOOL result;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000943 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
944 /* First try to use the system's implementation, if that is
945 available and either succeeds to gives an error other than
946 that it isn't implemented. */
947 check_gfax();
948 if (gfaxa) {
949 result = gfaxw(pszFile, level, pv);
950 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
951 return result;
952 }
953 /* It's either not present, or not implemented.
954 Emulate using FindFirstFile. */
955 if (level != GetFileExInfoStandard) {
956 SetLastError(ERROR_INVALID_PARAMETER);
957 return FALSE;
958 }
959 /* Use GetFileAttributes to validate that the file name
960 does not contain wildcards (which FindFirstFile would
961 accept). */
962 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
963 return FALSE;
Guido van Rossumd8faa362007-04-27 19:54:29 +0000964 return attributes_from_dir_w(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +0000965}
966
Martin v. Löwis14694662006-02-03 12:54:16 +0000967static int
968win32_stat(const char* path, struct win32_stat *result)
969{
970 WIN32_FILE_ATTRIBUTE_DATA info;
971 int code;
972 char *dot;
973 /* XXX not supported on Win95 and NT 3.x */
Thomas Wouters89f507f2006-12-13 04:49:30 +0000974 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
Guido van Rossumd8faa362007-04-27 19:54:29 +0000975 if (GetLastError() != ERROR_SHARING_VIOLATION) {
976 /* Protocol violation: we explicitly clear errno, instead of
977 setting it to a POSIX error. Callers should use GetLastError. */
978 errno = 0;
979 return -1;
980 } else {
981 /* Could not get attributes on open file. Fall back to
982 reading the directory. */
983 if (!attributes_from_dir(path, &info)) {
984 /* Very strange. This should not fail now */
985 errno = 0;
986 return -1;
987 }
988 }
Martin v. Löwis14694662006-02-03 12:54:16 +0000989 }
990 code = attribute_data_to_stat(&info, result);
991 if (code != 0)
992 return code;
993 /* Set S_IFEXEC if it is an .exe, .bat, ... */
994 dot = strrchr(path, '.');
995 if (dot) {
996 if (stricmp(dot, ".bat") == 0 ||
997 stricmp(dot, ".cmd") == 0 ||
998 stricmp(dot, ".exe") == 0 ||
999 stricmp(dot, ".com") == 0)
1000 result->st_mode |= 0111;
1001 }
1002 return code;
1003}
1004
1005static int
1006win32_wstat(const wchar_t* path, struct win32_stat *result)
1007{
1008 int code;
1009 const wchar_t *dot;
1010 WIN32_FILE_ATTRIBUTE_DATA info;
1011 /* XXX not supported on Win95 and NT 3.x */
Thomas Wouters89f507f2006-12-13 04:49:30 +00001012 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
Guido van Rossumd8faa362007-04-27 19:54:29 +00001013 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1014 /* Protocol violation: we explicitly clear errno, instead of
1015 setting it to a POSIX error. Callers should use GetLastError. */
1016 errno = 0;
1017 return -1;
1018 } else {
1019 /* Could not get attributes on open file. Fall back to
1020 reading the directory. */
1021 if (!attributes_from_dir_w(path, &info)) {
1022 /* Very strange. This should not fail now */
1023 errno = 0;
1024 return -1;
1025 }
1026 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001027 }
1028 code = attribute_data_to_stat(&info, result);
1029 if (code < 0)
1030 return code;
1031 /* Set IFEXEC if it is an .exe, .bat, ... */
1032 dot = wcsrchr(path, '.');
1033 if (dot) {
1034 if (_wcsicmp(dot, L".bat") == 0 ||
1035 _wcsicmp(dot, L".cmd") == 0 ||
1036 _wcsicmp(dot, L".exe") == 0 ||
1037 _wcsicmp(dot, L".com") == 0)
1038 result->st_mode |= 0111;
1039 }
1040 return code;
1041}
1042
1043static int
1044win32_fstat(int file_number, struct win32_stat *result)
1045{
1046 BY_HANDLE_FILE_INFORMATION info;
1047 HANDLE h;
1048 int type;
1049
1050 h = (HANDLE)_get_osfhandle(file_number);
1051
1052 /* Protocol violation: we explicitly clear errno, instead of
1053 setting it to a POSIX error. Callers should use GetLastError. */
1054 errno = 0;
1055
1056 if (h == INVALID_HANDLE_VALUE) {
1057 /* This is really a C library error (invalid file handle).
1058 We set the Win32 error to the closes one matching. */
1059 SetLastError(ERROR_INVALID_HANDLE);
1060 return -1;
1061 }
1062 memset(result, 0, sizeof(*result));
1063
1064 type = GetFileType(h);
1065 if (type == FILE_TYPE_UNKNOWN) {
1066 DWORD error = GetLastError();
1067 if (error != 0) {
1068 return -1;
1069 }
1070 /* else: valid but unknown file */
1071 }
1072
1073 if (type != FILE_TYPE_DISK) {
1074 if (type == FILE_TYPE_CHAR)
1075 result->st_mode = _S_IFCHR;
1076 else if (type == FILE_TYPE_PIPE)
1077 result->st_mode = _S_IFIFO;
1078 return 0;
1079 }
1080
1081 if (!GetFileInformationByHandle(h, &info)) {
1082 return -1;
1083 }
1084
1085 /* similar to stat() */
1086 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1087 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1088 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1089 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1090 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1091 /* specific to fstat() */
1092 result->st_nlink = info.nNumberOfLinks;
1093 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1094 return 0;
1095}
1096
1097#endif /* MS_WINDOWS */
1098
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001099PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001100"stat_result: Result from stat or lstat.\n\n\
1101This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001102 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001103or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1104\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001105Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1106or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001107\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001108See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001109
1110static PyStructSequence_Field stat_result_fields[] = {
1111 {"st_mode", "protection bits"},
1112 {"st_ino", "inode"},
1113 {"st_dev", "device"},
1114 {"st_nlink", "number of hard links"},
1115 {"st_uid", "user ID of owner"},
1116 {"st_gid", "group ID of owner"},
1117 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001118 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1119 {NULL, "integer time of last access"},
1120 {NULL, "integer time of last modification"},
1121 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001122 {"st_atime", "time of last access"},
1123 {"st_mtime", "time of last modification"},
1124 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001125#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001126 {"st_blksize", "blocksize for filesystem I/O"},
1127#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001128#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001129 {"st_blocks", "number of blocks allocated"},
1130#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001131#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001132 {"st_rdev", "device type (if inode device)"},
1133#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001134#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1135 {"st_flags", "user defined flags for file"},
1136#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001137#ifdef HAVE_STRUCT_STAT_ST_GEN
1138 {"st_gen", "generation number"},
1139#endif
1140#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1141 {"st_birthtime", "time of creation"},
1142#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001143 {0}
1144};
1145
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001146#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001147#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001148#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001149#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001150#endif
1151
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001152#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001153#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1154#else
1155#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1156#endif
1157
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001158#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001159#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1160#else
1161#define ST_RDEV_IDX ST_BLOCKS_IDX
1162#endif
1163
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001164#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1165#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1166#else
1167#define ST_FLAGS_IDX ST_RDEV_IDX
1168#endif
1169
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001170#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001171#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001172#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001173#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001174#endif
1175
1176#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1177#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1178#else
1179#define ST_BIRTHTIME_IDX ST_GEN_IDX
1180#endif
1181
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001182static PyStructSequence_Desc stat_result_desc = {
1183 "stat_result", /* name */
1184 stat_result__doc__, /* doc */
1185 stat_result_fields,
1186 10
1187};
1188
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001189PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001190"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1191This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001192 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001193or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001194\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001195See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001196
1197static PyStructSequence_Field statvfs_result_fields[] = {
1198 {"f_bsize", },
1199 {"f_frsize", },
1200 {"f_blocks", },
1201 {"f_bfree", },
1202 {"f_bavail", },
1203 {"f_files", },
1204 {"f_ffree", },
1205 {"f_favail", },
1206 {"f_flag", },
1207 {"f_namemax",},
1208 {0}
1209};
1210
1211static PyStructSequence_Desc statvfs_result_desc = {
1212 "statvfs_result", /* name */
1213 statvfs_result__doc__, /* doc */
1214 statvfs_result_fields,
1215 10
1216};
1217
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001218static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001219static PyTypeObject StatResultType;
1220static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001221static newfunc structseq_new;
1222
1223static PyObject *
1224statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1225{
1226 PyStructSequence *result;
1227 int i;
1228
1229 result = (PyStructSequence*)structseq_new(type, args, kwds);
1230 if (!result)
1231 return NULL;
1232 /* If we have been initialized from a tuple,
1233 st_?time might be set to None. Initialize it
1234 from the int slots. */
1235 for (i = 7; i <= 9; i++) {
1236 if (result->ob_item[i+3] == Py_None) {
1237 Py_DECREF(Py_None);
1238 Py_INCREF(result->ob_item[i]);
1239 result->ob_item[i+3] = result->ob_item[i];
1240 }
1241 }
1242 return (PyObject*)result;
1243}
1244
1245
1246
1247/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001248static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001249
1250PyDoc_STRVAR(stat_float_times__doc__,
1251"stat_float_times([newval]) -> oldval\n\n\
1252Determine whether os.[lf]stat represents time stamps as float objects.\n\
1253If newval is True, future calls to stat() return floats, if it is False,\n\
1254future calls return ints. \n\
1255If newval is omitted, return the current setting.\n");
1256
1257static PyObject*
1258stat_float_times(PyObject* self, PyObject *args)
1259{
1260 int newval = -1;
1261 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1262 return NULL;
1263 if (newval == -1)
1264 /* Return old value */
1265 return PyBool_FromLong(_stat_float_times);
1266 _stat_float_times = newval;
1267 Py_INCREF(Py_None);
1268 return Py_None;
1269}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001270
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001271static void
1272fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1273{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001274 PyObject *fval,*ival;
1275#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001276 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001277#else
1278 ival = PyInt_FromLong((long)sec);
1279#endif
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001280 if (!ival)
1281 return;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001282 if (_stat_float_times) {
1283 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1284 } else {
1285 fval = ival;
1286 Py_INCREF(fval);
1287 }
1288 PyStructSequence_SET_ITEM(v, index, ival);
1289 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001290}
1291
Tim Peters5aa91602002-01-30 05:46:57 +00001292/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001293 (used by posix_stat() and posix_fstat()) */
1294static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001295_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001296{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001297 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001298 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001299 if (v == NULL)
1300 return NULL;
1301
Martin v. Löwis14694662006-02-03 12:54:16 +00001302 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001303#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001304 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001305 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001306#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001307 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001308#endif
1309#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001310 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001311 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001312#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001313 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001314#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001315 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1316 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1317 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001318#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001319 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001320 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001321#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001322 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001323#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001324
Martin v. Löwis14694662006-02-03 12:54:16 +00001325#if defined(HAVE_STAT_TV_NSEC)
1326 ansec = st->st_atim.tv_nsec;
1327 mnsec = st->st_mtim.tv_nsec;
1328 cnsec = st->st_ctim.tv_nsec;
1329#elif defined(HAVE_STAT_TV_NSEC2)
1330 ansec = st->st_atimespec.tv_nsec;
1331 mnsec = st->st_mtimespec.tv_nsec;
1332 cnsec = st->st_ctimespec.tv_nsec;
1333#elif defined(HAVE_STAT_NSEC)
1334 ansec = st->st_atime_nsec;
1335 mnsec = st->st_mtime_nsec;
1336 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001337#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001338 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001339#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001340 fill_time(v, 7, st->st_atime, ansec);
1341 fill_time(v, 8, st->st_mtime, mnsec);
1342 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001343
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001344#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001345 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001346 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001347#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001348#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001349 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001350 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001351#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001352#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001353 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001354 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001355#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001356#ifdef HAVE_STRUCT_STAT_ST_GEN
1357 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001358 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001359#endif
1360#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1361 {
1362 PyObject *val;
1363 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001364 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001365#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001366 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001367#else
1368 bnsec = 0;
1369#endif
1370 if (_stat_float_times) {
1371 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1372 } else {
1373 val = PyInt_FromLong((long)bsec);
1374 }
1375 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1376 val);
1377 }
1378#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001379#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1380 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001381 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001382#endif
Fred Drake699f3522000-06-29 21:12:41 +00001383
1384 if (PyErr_Occurred()) {
1385 Py_DECREF(v);
1386 return NULL;
1387 }
1388
1389 return v;
1390}
1391
Martin v. Löwisd8948722004-06-02 09:57:56 +00001392#ifdef MS_WINDOWS
1393
1394/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1395 where / can be used in place of \ and the trailing slash is optional.
1396 Both SERVER and SHARE must have at least one character.
1397*/
1398
1399#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1400#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001401#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001402#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001403#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001404
Tim Peters4ad82172004-08-30 17:02:04 +00001405static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001406IsUNCRootA(char *path, int pathlen)
1407{
1408 #define ISSLASH ISSLASHA
1409
1410 int i, share;
1411
1412 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1413 /* minimum UNCRoot is \\x\y */
1414 return FALSE;
1415 for (i = 2; i < pathlen ; i++)
1416 if (ISSLASH(path[i])) break;
1417 if (i == 2 || i == pathlen)
1418 /* do not allow \\\SHARE or \\SERVER */
1419 return FALSE;
1420 share = i+1;
1421 for (i = share; i < pathlen; i++)
1422 if (ISSLASH(path[i])) break;
1423 return (i != share && (i == pathlen || i == pathlen-1));
1424
1425 #undef ISSLASH
1426}
1427
1428#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001429static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001430IsUNCRootW(Py_UNICODE *path, int pathlen)
1431{
1432 #define ISSLASH ISSLASHW
1433
1434 int i, share;
1435
1436 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1437 /* minimum UNCRoot is \\x\y */
1438 return FALSE;
1439 for (i = 2; i < pathlen ; i++)
1440 if (ISSLASH(path[i])) break;
1441 if (i == 2 || i == pathlen)
1442 /* do not allow \\\SHARE or \\SERVER */
1443 return FALSE;
1444 share = i+1;
1445 for (i = share; i < pathlen; i++)
1446 if (ISSLASH(path[i])) break;
1447 return (i != share && (i == pathlen || i == pathlen-1));
1448
1449 #undef ISSLASH
1450}
1451#endif /* Py_WIN_WIDE_FILENAMES */
1452#endif /* MS_WINDOWS */
1453
Barry Warsaw53699e91996-12-10 23:23:01 +00001454static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001455posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001456 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001457#ifdef __VMS
1458 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1459#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001460 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001461#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001462 char *wformat,
1463 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001464{
Fred Drake699f3522000-06-29 21:12:41 +00001465 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001466 char *path = NULL; /* pass this to stat; do not free() it */
1467 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001468 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001469 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001470
1471#ifdef Py_WIN_WIDE_FILENAMES
1472 /* If on wide-character-capable OS see if argument
1473 is Unicode and if so use wide API. */
1474 if (unicode_file_names()) {
1475 PyUnicodeObject *po;
1476 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001477 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1478
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001479 Py_BEGIN_ALLOW_THREADS
1480 /* PyUnicode_AS_UNICODE result OK without
1481 thread lock as it is a simple dereference. */
1482 res = wstatfunc(wpath, &st);
1483 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001484
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001485 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001486 return win32_error_unicode("stat", wpath);
1487 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001488 }
1489 /* Drop the argument parsing error as narrow strings
1490 are also valid. */
1491 PyErr_Clear();
1492 }
1493#endif
1494
Tim Peters5aa91602002-01-30 05:46:57 +00001495 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001496 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001497 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001498 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001499
Barry Warsaw53699e91996-12-10 23:23:01 +00001500 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001501 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001502 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001503
1504 if (res != 0) {
1505#ifdef MS_WINDOWS
1506 result = win32_error("stat", pathfree);
1507#else
1508 result = posix_error_with_filename(pathfree);
1509#endif
1510 }
1511 else
1512 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001513
Tim Peters500bd032001-12-19 19:05:01 +00001514 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001515 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001516}
1517
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001518/* POSIX methods */
1519
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001520PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001521"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001522Use the real uid/gid to test for access to a path. Note that most\n\
1523operations will use the effective uid/gid, therefore this routine can\n\
1524be used in a suid/sgid environment to test if the invoking user has the\n\
1525specified access to the path. The mode argument can be F_OK to test\n\
1526existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001527
1528static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001529posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001530{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001531 char *path;
1532 int mode;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001533
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001534#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001535 DWORD attr;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001536 if (unicode_file_names()) {
1537 PyUnicodeObject *po;
1538 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1539 Py_BEGIN_ALLOW_THREADS
1540 /* PyUnicode_AS_UNICODE OK without thread lock as
1541 it is a simple dereference. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001542 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001543 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001544 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001545 }
1546 /* Drop the argument parsing error as narrow strings
1547 are also valid. */
1548 PyErr_Clear();
1549 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001550 if (!PyArg_ParseTuple(args, "eti:access",
1551 Py_FileSystemDefaultEncoding, &path, &mode))
1552 return 0;
1553 Py_BEGIN_ALLOW_THREADS
1554 attr = GetFileAttributesA(path);
1555 Py_END_ALLOW_THREADS
1556 PyMem_Free(path);
1557finish:
1558 if (attr == 0xFFFFFFFF)
1559 /* File does not exist, or cannot read attributes */
1560 return PyBool_FromLong(0);
1561 /* Access is possible if either write access wasn't requested, or
1562 the file isn't read-only. */
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001563 return PyBool_FromLong(!(mode & 2) || !(attr & FILE_ATTRIBUTE_READONLY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001564#else
1565 int res;
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001566 if (!PyArg_ParseTuple(args, "eti:access",
1567 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001568 return NULL;
1569 Py_BEGIN_ALLOW_THREADS
1570 res = access(path, mode);
1571 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001572 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001573 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001574#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001575}
1576
Guido van Rossumd371ff11999-01-25 16:12:23 +00001577#ifndef F_OK
1578#define F_OK 0
1579#endif
1580#ifndef R_OK
1581#define R_OK 4
1582#endif
1583#ifndef W_OK
1584#define W_OK 2
1585#endif
1586#ifndef X_OK
1587#define X_OK 1
1588#endif
1589
1590#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001591PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001592"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001593Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001594
1595static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001596posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001597{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001598 int id;
1599 char *ret;
1600
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001601 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001602 return NULL;
1603
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001604#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001605 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001606 if (id == 0) {
1607 ret = ttyname();
1608 }
1609 else {
1610 ret = NULL;
1611 }
1612#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001613 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001614#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001615 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001616 return posix_error();
Neal Norwitz93c56822007-08-26 07:10:06 +00001617 return PyUnicode_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001618}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001619#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001620
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001621#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001622PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001623"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001624Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001625
1626static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001627posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001628{
1629 char *ret;
1630 char buffer[L_ctermid];
1631
Greg Wardb48bc172000-03-01 21:51:56 +00001632#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001633 ret = ctermid_r(buffer);
1634#else
1635 ret = ctermid(buffer);
1636#endif
1637 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001638 return posix_error();
Neal Norwitz93c56822007-08-26 07:10:06 +00001639 return PyUnicode_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001640}
1641#endif
1642
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001643PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001644"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001645Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001646
Barry Warsaw53699e91996-12-10 23:23:01 +00001647static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001648posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001649{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001650#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001651 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001652#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001653 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001654#elif defined(__VMS)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001655 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001656#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00001657 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001658#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001659}
1660
Fred Drake4d1e64b2002-04-15 19:40:07 +00001661#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001662PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001663"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001664Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001665opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001666
1667static PyObject *
1668posix_fchdir(PyObject *self, PyObject *fdobj)
1669{
1670 return posix_fildes(fdobj, fchdir);
1671}
1672#endif /* HAVE_FCHDIR */
1673
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001674
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001675PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001676"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001677Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001678
Barry Warsaw53699e91996-12-10 23:23:01 +00001679static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001680posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001681{
Mark Hammondef8b6542001-05-13 08:04:26 +00001682 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001683 int i;
1684 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001685#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001686 DWORD attr;
Mark Hammond817c9292003-12-03 01:22:38 +00001687 if (unicode_file_names()) {
1688 PyUnicodeObject *po;
1689 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1690 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001691 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1692 if (attr != 0xFFFFFFFF) {
1693 if (i & _S_IWRITE)
1694 attr &= ~FILE_ATTRIBUTE_READONLY;
1695 else
1696 attr |= FILE_ATTRIBUTE_READONLY;
1697 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1698 }
1699 else
1700 res = 0;
Mark Hammond817c9292003-12-03 01:22:38 +00001701 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001702 if (!res)
1703 return win32_error_unicode("chmod",
Mark Hammond817c9292003-12-03 01:22:38 +00001704 PyUnicode_AS_UNICODE(po));
1705 Py_INCREF(Py_None);
1706 return Py_None;
1707 }
1708 /* Drop the argument parsing error as narrow strings
1709 are also valid. */
1710 PyErr_Clear();
1711 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001712 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1713 &path, &i))
1714 return NULL;
1715 Py_BEGIN_ALLOW_THREADS
1716 attr = GetFileAttributesA(path);
1717 if (attr != 0xFFFFFFFF) {
1718 if (i & _S_IWRITE)
1719 attr &= ~FILE_ATTRIBUTE_READONLY;
1720 else
1721 attr |= FILE_ATTRIBUTE_READONLY;
1722 res = SetFileAttributesA(path, attr);
1723 }
1724 else
1725 res = 0;
1726 Py_END_ALLOW_THREADS
1727 if (!res) {
1728 win32_error("chmod", path);
1729 PyMem_Free(path);
1730 return NULL;
1731 }
1732 PyMem_Free(path);
1733 Py_INCREF(Py_None);
1734 return Py_None;
1735#else /* Py_WIN_WIDE_FILENAMES */
Mark Hammond817c9292003-12-03 01:22:38 +00001736 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001737 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001738 return NULL;
1739 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001740 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001741 Py_END_ALLOW_THREADS
1742 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001743 return posix_error_with_allocated_filename(path);
1744 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001745 Py_INCREF(Py_None);
1746 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001747#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001748}
1749
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001750
Thomas Wouterscf297e42007-02-23 15:07:44 +00001751#ifdef HAVE_CHFLAGS
1752PyDoc_STRVAR(posix_chflags__doc__,
1753"chflags(path, flags)\n\n\
1754Set file flags.");
1755
1756static PyObject *
1757posix_chflags(PyObject *self, PyObject *args)
1758{
1759 char *path;
1760 unsigned long flags;
1761 int res;
1762 if (!PyArg_ParseTuple(args, "etk:chflags",
1763 Py_FileSystemDefaultEncoding, &path, &flags))
1764 return NULL;
1765 Py_BEGIN_ALLOW_THREADS
1766 res = chflags(path, flags);
1767 Py_END_ALLOW_THREADS
1768 if (res < 0)
1769 return posix_error_with_allocated_filename(path);
1770 PyMem_Free(path);
1771 Py_INCREF(Py_None);
1772 return Py_None;
1773}
1774#endif /* HAVE_CHFLAGS */
1775
1776#ifdef HAVE_LCHFLAGS
1777PyDoc_STRVAR(posix_lchflags__doc__,
1778"lchflags(path, flags)\n\n\
1779Set file flags.\n\
1780This function will not follow symbolic links.");
1781
1782static PyObject *
1783posix_lchflags(PyObject *self, PyObject *args)
1784{
1785 char *path;
1786 unsigned long flags;
1787 int res;
1788 if (!PyArg_ParseTuple(args, "etk:lchflags",
1789 Py_FileSystemDefaultEncoding, &path, &flags))
1790 return NULL;
1791 Py_BEGIN_ALLOW_THREADS
1792 res = lchflags(path, flags);
1793 Py_END_ALLOW_THREADS
1794 if (res < 0)
1795 return posix_error_with_allocated_filename(path);
1796 PyMem_Free(path);
1797 Py_INCREF(Py_None);
1798 return Py_None;
1799}
1800#endif /* HAVE_LCHFLAGS */
1801
Martin v. Löwis244edc82001-10-04 22:44:26 +00001802#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001803PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001804"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001805Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001806
1807static PyObject *
1808posix_chroot(PyObject *self, PyObject *args)
1809{
Thomas Wouters477c8d52006-05-27 19:21:47 +00001810 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001811}
1812#endif
1813
Guido van Rossum21142a01999-01-08 21:05:37 +00001814#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001815PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001816"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001817force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001818
1819static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001820posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001821{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001822 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001823}
1824#endif /* HAVE_FSYNC */
1825
1826#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001827
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001828#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001829extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1830#endif
1831
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001832PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001833"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001834force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001835 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001836
1837static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001838posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001839{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001840 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001841}
1842#endif /* HAVE_FDATASYNC */
1843
1844
Fredrik Lundh10723342000-07-10 16:38:09 +00001845#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001846PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001847"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001848Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001849
Barry Warsaw53699e91996-12-10 23:23:01 +00001850static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001851posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001852{
Mark Hammondef8b6542001-05-13 08:04:26 +00001853 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001854 int uid, gid;
1855 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001856 if (!PyArg_ParseTuple(args, "etii:chown",
1857 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001858 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001859 return NULL;
1860 Py_BEGIN_ALLOW_THREADS
1861 res = chown(path, (uid_t) uid, (gid_t) gid);
1862 Py_END_ALLOW_THREADS
1863 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001864 return posix_error_with_allocated_filename(path);
1865 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001866 Py_INCREF(Py_None);
1867 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001868}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001869#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001870
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001871#ifdef HAVE_LCHOWN
1872PyDoc_STRVAR(posix_lchown__doc__,
1873"lchown(path, uid, gid)\n\n\
1874Change the owner and group id of path to the numeric uid and gid.\n\
1875This function will not follow symbolic links.");
1876
1877static PyObject *
1878posix_lchown(PyObject *self, PyObject *args)
1879{
1880 char *path = NULL;
1881 int uid, gid;
1882 int res;
1883 if (!PyArg_ParseTuple(args, "etii:lchown",
1884 Py_FileSystemDefaultEncoding, &path,
1885 &uid, &gid))
1886 return NULL;
1887 Py_BEGIN_ALLOW_THREADS
1888 res = lchown(path, (uid_t) uid, (gid_t) gid);
1889 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001890 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001891 return posix_error_with_allocated_filename(path);
1892 PyMem_Free(path);
1893 Py_INCREF(Py_None);
1894 return Py_None;
1895}
1896#endif /* HAVE_LCHOWN */
1897
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001898
Guido van Rossum36bc6801995-06-14 22:54:23 +00001899#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001900PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001901"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001902Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001903
Barry Warsaw53699e91996-12-10 23:23:01 +00001904static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001905posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001906{
1907 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001908 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001909
Barry Warsaw53699e91996-12-10 23:23:01 +00001910 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001911#if defined(PYOS_OS2) && defined(PYCC_GCC)
1912 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001913#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001914 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001915#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001916 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001917 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001918 return posix_error();
Neal Norwitz93c56822007-08-26 07:10:06 +00001919 return PyUnicode_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001920}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001921
1922PyDoc_STRVAR(posix_getcwdu__doc__,
1923"getcwdu() -> path\n\n\
1924Return a unicode string representing the current working directory.");
1925
1926static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001927posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001928{
1929 char buf[1026];
1930 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001931
1932#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001933 DWORD len;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001934 if (unicode_file_names()) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001935 wchar_t wbuf[1026];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001936 wchar_t *wbuf2 = wbuf;
1937 PyObject *resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001938 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001939 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
1940 /* If the buffer is large enough, len does not include the
1941 terminating \0. If the buffer is too small, len includes
1942 the space needed for the terminator. */
1943 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
1944 wbuf2 = malloc(len * sizeof(wchar_t));
1945 if (wbuf2)
1946 len = GetCurrentDirectoryW(len, wbuf2);
1947 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001948 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001949 if (!wbuf2) {
1950 PyErr_NoMemory();
1951 return NULL;
1952 }
1953 if (!len) {
1954 if (wbuf2 != wbuf) free(wbuf2);
1955 return win32_error("getcwdu", NULL);
1956 }
1957 resobj = PyUnicode_FromWideChar(wbuf2, len);
1958 if (wbuf2 != wbuf) free(wbuf2);
1959 return resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001960 }
1961#endif
1962
1963 Py_BEGIN_ALLOW_THREADS
1964#if defined(PYOS_OS2) && defined(PYCC_GCC)
1965 res = _getcwd2(buf, sizeof buf);
1966#else
1967 res = getcwd(buf, sizeof buf);
1968#endif
1969 Py_END_ALLOW_THREADS
1970 if (res == NULL)
1971 return posix_error();
1972 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1973}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001974#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001975
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001976
Guido van Rossumb6775db1994-08-01 11:34:53 +00001977#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001978PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001979"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001980Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001981
Barry Warsaw53699e91996-12-10 23:23:01 +00001982static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001983posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001984{
Thomas Wouters477c8d52006-05-27 19:21:47 +00001985 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001986}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001987#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001988
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001989
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001990PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001991"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001992Return a list containing the names of the entries in the directory.\n\
1993\n\
1994 path: path of directory to list\n\
1995\n\
1996The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001997entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001998
Barry Warsaw53699e91996-12-10 23:23:01 +00001999static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002000posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002001{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002002 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002003 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002004#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002005
Barry Warsaw53699e91996-12-10 23:23:01 +00002006 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002007 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002008 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002009 WIN32_FIND_DATA FileData;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002010 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00002011 char *bufptr = namebuf;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002012 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002013
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002014#ifdef Py_WIN_WIDE_FILENAMES
2015 /* If on wide-character-capable OS see if argument
2016 is Unicode and if so use wide API. */
2017 if (unicode_file_names()) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002018 PyObject *po;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002019 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2020 WIN32_FIND_DATAW wFileData;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002021 Py_UNICODE *wnamebuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002022 Py_UNICODE wch;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002023 /* Overallocate for \\*.*\0 */
2024 len = PyUnicode_GET_SIZE(po);
2025 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2026 if (!wnamebuf) {
2027 PyErr_NoMemory();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002028 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002029 }
2030 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2031 wch = len > 0 ? wnamebuf[len-1] : '\0';
2032 if (wch != L'/' && wch != L'\\' && wch != L':')
2033 wnamebuf[len++] = L'\\';
2034 wcscpy(wnamebuf + len, L"*.*");
2035 if ((d = PyList_New(0)) == NULL) {
2036 free(wnamebuf);
2037 return NULL;
2038 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002039 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2040 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002041 int error = GetLastError();
2042 if (error == ERROR_FILE_NOT_FOUND) {
2043 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002044 return d;
2045 }
2046 Py_DECREF(d);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002047 win32_error_unicode("FindFirstFileW", wnamebuf);
2048 free(wnamebuf);
2049 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002050 }
2051 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002052 /* Skip over . and .. */
2053 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2054 wcscmp(wFileData.cFileName, L"..") != 0) {
2055 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2056 if (v == NULL) {
2057 Py_DECREF(d);
2058 d = NULL;
2059 break;
2060 }
2061 if (PyList_Append(d, v) != 0) {
2062 Py_DECREF(v);
2063 Py_DECREF(d);
2064 d = NULL;
2065 break;
2066 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002067 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002068 }
Georg Brandl622927b2006-03-07 12:48:03 +00002069 Py_BEGIN_ALLOW_THREADS
2070 result = FindNextFileW(hFindFile, &wFileData);
2071 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002072 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2073 it got to the end of the directory. */
2074 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2075 Py_DECREF(d);
2076 win32_error_unicode("FindNextFileW", wnamebuf);
2077 FindClose(hFindFile);
2078 free(wnamebuf);
2079 return NULL;
2080 }
Georg Brandl622927b2006-03-07 12:48:03 +00002081 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002082
2083 if (FindClose(hFindFile) == FALSE) {
2084 Py_DECREF(d);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002085 win32_error_unicode("FindClose", wnamebuf);
2086 free(wnamebuf);
2087 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002088 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002089 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002090 return d;
2091 }
2092 /* Drop the argument parsing error as narrow strings
2093 are also valid. */
2094 PyErr_Clear();
2095 }
2096#endif
2097
Tim Peters5aa91602002-01-30 05:46:57 +00002098 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002099 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00002100 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002101 if (len > 0) {
2102 char ch = namebuf[len-1];
2103 if (ch != SEP && ch != ALTSEP && ch != ':')
2104 namebuf[len++] = '/';
2105 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002106 strcpy(namebuf + len, "*.*");
2107
Barry Warsaw53699e91996-12-10 23:23:01 +00002108 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002109 return NULL;
2110
2111 hFindFile = FindFirstFile(namebuf, &FileData);
2112 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002113 int error = GetLastError();
2114 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002115 return d;
2116 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002117 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002118 }
2119 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002120 /* Skip over . and .. */
2121 if (strcmp(FileData.cFileName, ".") != 0 &&
2122 strcmp(FileData.cFileName, "..") != 0) {
2123 v = PyString_FromString(FileData.cFileName);
2124 if (v == NULL) {
2125 Py_DECREF(d);
2126 d = NULL;
2127 break;
2128 }
2129 if (PyList_Append(d, v) != 0) {
2130 Py_DECREF(v);
2131 Py_DECREF(d);
2132 d = NULL;
2133 break;
2134 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002135 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002136 }
Georg Brandl622927b2006-03-07 12:48:03 +00002137 Py_BEGIN_ALLOW_THREADS
2138 result = FindNextFile(hFindFile, &FileData);
2139 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002140 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2141 it got to the end of the directory. */
2142 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2143 Py_DECREF(d);
2144 win32_error("FindNextFile", namebuf);
2145 FindClose(hFindFile);
2146 return NULL;
2147 }
Georg Brandl622927b2006-03-07 12:48:03 +00002148 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002149
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002150 if (FindClose(hFindFile) == FALSE) {
2151 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002152 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002153 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002154
2155 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002156
Tim Peters0bb44a42000-09-15 07:44:49 +00002157#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002158
2159#ifndef MAX_PATH
2160#define MAX_PATH CCHMAXPATH
2161#endif
2162 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002163 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002164 PyObject *d, *v;
2165 char namebuf[MAX_PATH+5];
2166 HDIR hdir = 1;
2167 ULONG srchcnt = 1;
2168 FILEFINDBUF3 ep;
2169 APIRET rc;
2170
Alexandre Vassalotti70a23712007-10-14 02:05:51 +00002171 if (!PyArg_ParseTuple(args, "et#:listdir",
2172 Py_FileSystemDefaultEncoding, &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002173 return NULL;
2174 if (len >= MAX_PATH) {
Neal Norwitz6c913782007-10-14 03:23:09 +00002175 PyMem_Free(name);
2176 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002177 return NULL;
2178 }
2179 strcpy(namebuf, name);
2180 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002181 if (*pt == ALTSEP)
2182 *pt = SEP;
2183 if (namebuf[len-1] != SEP)
2184 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002185 strcpy(namebuf + len, "*.*");
2186
Neal Norwitz6c913782007-10-14 03:23:09 +00002187 if ((d = PyList_New(0)) == NULL) {
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002188 PyMem_Free(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002189 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002190 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002191
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002192 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2193 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002194 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002195 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2196 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2197 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002198
2199 if (rc != NO_ERROR) {
2200 errno = ENOENT;
Neal Norwitz6c913782007-10-14 03:23:09 +00002201 return posix_error_with_allocated_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002202 }
2203
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002204 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002205 do {
2206 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002207 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002208 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002209
2210 strcpy(namebuf, ep.achName);
2211
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002212 /* Leave Case of Name Alone -- In Native Form */
2213 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002214
2215 v = PyString_FromString(namebuf);
2216 if (v == NULL) {
2217 Py_DECREF(d);
2218 d = NULL;
2219 break;
2220 }
2221 if (PyList_Append(d, v) != 0) {
2222 Py_DECREF(v);
2223 Py_DECREF(d);
2224 d = NULL;
2225 break;
2226 }
2227 Py_DECREF(v);
2228 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2229 }
2230
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002231 PyMem_Free(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002232 return d;
2233#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002234
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002235 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002236 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002237 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002238 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00002239 int arg_is_unicode = 1;
2240
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002241 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002242 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2243 arg_is_unicode = 0;
2244 PyErr_Clear();
2245 }
2246 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002247 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002248 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002249 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002250 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002251 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002252 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002253 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002254 return NULL;
2255 }
Georg Brandl622927b2006-03-07 12:48:03 +00002256 for (;;) {
2257 Py_BEGIN_ALLOW_THREADS
2258 ep = readdir(dirp);
2259 Py_END_ALLOW_THREADS
2260 if (ep == NULL)
2261 break;
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002262 if (ep->d_name[0] == '.' &&
2263 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002264 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002265 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00002266 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002267 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002268 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002269 d = NULL;
2270 break;
2271 }
Just van Rossum96b1c902003-03-03 17:32:15 +00002272 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002273 PyObject *w;
2274
2275 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002276 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00002277 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00002278 if (w != NULL) {
2279 Py_DECREF(v);
2280 v = w;
2281 }
2282 else {
2283 /* fall back to the original byte string, as
2284 discussed in patch #683592 */
2285 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00002286 }
Just van Rossum46c97842003-02-25 21:42:15 +00002287 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002288 if (PyList_Append(d, v) != 0) {
2289 Py_DECREF(v);
2290 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002291 d = NULL;
2292 break;
2293 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002294 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002295 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002296 if (errno != 0 && d != NULL) {
2297 /* readdir() returned NULL and set errno */
2298 closedir(dirp);
2299 Py_DECREF(d);
2300 return posix_error_with_allocated_filename(name);
2301 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002302 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002303 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002304
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002305 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002306
Tim Peters0bb44a42000-09-15 07:44:49 +00002307#endif /* which OS */
2308} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002309
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002310#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002311/* A helper function for abspath on win32 */
2312static PyObject *
2313posix__getfullpathname(PyObject *self, PyObject *args)
2314{
2315 /* assume encoded strings wont more than double no of chars */
2316 char inbuf[MAX_PATH*2];
2317 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00002318 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002319 char outbuf[MAX_PATH*2];
2320 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002321#ifdef Py_WIN_WIDE_FILENAMES
2322 if (unicode_file_names()) {
2323 PyUnicodeObject *po;
2324 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2325 Py_UNICODE woutbuf[MAX_PATH*2];
2326 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00002327 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002328 sizeof(woutbuf)/sizeof(woutbuf[0]),
2329 woutbuf, &wtemp))
2330 return win32_error("GetFullPathName", "");
2331 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
2332 }
2333 /* Drop the argument parsing error as narrow strings
2334 are also valid. */
2335 PyErr_Clear();
2336 }
2337#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002338 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2339 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00002340 &insize))
2341 return NULL;
2342 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2343 outbuf, &temp))
2344 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002345 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2346 return PyUnicode_Decode(outbuf, strlen(outbuf),
2347 Py_FileSystemDefaultEncoding, NULL);
2348 }
Mark Hammondef8b6542001-05-13 08:04:26 +00002349 return PyString_FromString(outbuf);
2350} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002351#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002352
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002353PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002354"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002355Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002356
Barry Warsaw53699e91996-12-10 23:23:01 +00002357static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002358posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002359{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002360 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00002361 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002362 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002363
2364#ifdef Py_WIN_WIDE_FILENAMES
2365 if (unicode_file_names()) {
2366 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00002367 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002368 Py_BEGIN_ALLOW_THREADS
2369 /* PyUnicode_AS_UNICODE OK without thread lock as
2370 it is a simple dereference. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002371 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002372 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002373 if (!res)
2374 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002375 Py_INCREF(Py_None);
2376 return Py_None;
2377 }
2378 /* Drop the argument parsing error as narrow strings
2379 are also valid. */
2380 PyErr_Clear();
2381 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002382 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2383 Py_FileSystemDefaultEncoding, &path, &mode))
2384 return NULL;
2385 Py_BEGIN_ALLOW_THREADS
2386 /* PyUnicode_AS_UNICODE OK without thread lock as
2387 it is a simple dereference. */
2388 res = CreateDirectoryA(path, NULL);
2389 Py_END_ALLOW_THREADS
2390 if (!res) {
2391 win32_error("mkdir", path);
2392 PyMem_Free(path);
2393 return NULL;
2394 }
2395 PyMem_Free(path);
2396 Py_INCREF(Py_None);
2397 return Py_None;
2398#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002399
Tim Peters5aa91602002-01-30 05:46:57 +00002400 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002401 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002402 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002403 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002404#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002405 res = mkdir(path);
2406#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002407 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002408#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002409 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002410 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002411 return posix_error_with_allocated_filename(path);
2412 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002413 Py_INCREF(Py_None);
2414 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002415#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002416}
2417
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002418
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002419/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2420#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002421#include <sys/resource.h>
2422#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002423
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002424
2425#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002426PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002427"nice(inc) -> new_priority\n\n\
2428Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002429
Barry Warsaw53699e91996-12-10 23:23:01 +00002430static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002431posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002432{
2433 int increment, value;
2434
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002435 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002436 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002437
2438 /* There are two flavours of 'nice': one that returns the new
2439 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002440 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2441 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002442
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002443 If we are of the nice family that returns the new priority, we
2444 need to clear errno before the call, and check if errno is filled
2445 before calling posix_error() on a returnvalue of -1, because the
2446 -1 may be the actual new priority! */
2447
2448 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002449 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002450#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002451 if (value == 0)
2452 value = getpriority(PRIO_PROCESS, 0);
2453#endif
2454 if (value == -1 && errno != 0)
2455 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002456 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002457 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002458}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002459#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002460
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002461PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002462"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002463Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002464
Barry Warsaw53699e91996-12-10 23:23:01 +00002465static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002466posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002467{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002468#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002469 PyObject *o1, *o2;
2470 char *p1, *p2;
2471 BOOL result;
2472 if (unicode_file_names()) {
2473 if (!PyArg_ParseTuple(args, "O&O&:rename",
2474 convert_to_unicode, &o1,
2475 convert_to_unicode, &o2))
2476 PyErr_Clear();
2477 else {
2478 Py_BEGIN_ALLOW_THREADS
2479 result = MoveFileW(PyUnicode_AsUnicode(o1),
2480 PyUnicode_AsUnicode(o2));
2481 Py_END_ALLOW_THREADS
2482 Py_DECREF(o1);
2483 Py_DECREF(o2);
2484 if (!result)
2485 return win32_error("rename", NULL);
2486 Py_INCREF(Py_None);
2487 return Py_None;
2488 }
2489 }
2490 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2491 return NULL;
2492 Py_BEGIN_ALLOW_THREADS
2493 result = MoveFileA(p1, p2);
2494 Py_END_ALLOW_THREADS
2495 if (!result)
2496 return win32_error("rename", NULL);
2497 Py_INCREF(Py_None);
2498 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002499#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002500 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002501#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002502}
2503
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002504
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002505PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002506"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002507Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002508
Barry Warsaw53699e91996-12-10 23:23:01 +00002509static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002510posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002511{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002512#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002513 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002514#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002515 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002516#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002517}
2518
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002519
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002520PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002521"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002522Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002523
Barry Warsaw53699e91996-12-10 23:23:01 +00002524static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002525posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002526{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002527#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002528 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002529#else
2530 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2531#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002532}
2533
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002534
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002535#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002536PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002537"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002538Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002539
Barry Warsaw53699e91996-12-10 23:23:01 +00002540static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002541posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002542{
Guido van Rossumff4949e1992-08-05 19:58:53 +00002543 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002544#ifdef MS_WINDOWS
2545 wchar_t *command;
2546 if (!PyArg_ParseTuple(args, "u:system", &command))
2547 return NULL;
2548#else
2549 char *command;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002550 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002551 return NULL;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002552#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002553 Py_BEGIN_ALLOW_THREADS
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002554#ifdef MS_WINDOWS
2555 sts = _wsystem(command);
2556#else
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002557 sts = system(command);
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002558#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002559 Py_END_ALLOW_THREADS
2560 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002561}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002562#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002563
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002564
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002565PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002566"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002567Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002568
Barry Warsaw53699e91996-12-10 23:23:01 +00002569static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002570posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002571{
2572 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002573 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002574 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002575 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002576 if (i < 0)
2577 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002578 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002579}
2580
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002581
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002582PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002583"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002584Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002585
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002586PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002587"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002588Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002589
Barry Warsaw53699e91996-12-10 23:23:01 +00002590static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002591posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002592{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002593#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002594 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002595#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002596 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002597#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002598}
2599
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002600
Guido van Rossumb6775db1994-08-01 11:34:53 +00002601#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002602PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002603"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002604Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002605
Barry Warsaw53699e91996-12-10 23:23:01 +00002606static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002607posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002608{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002609 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002610 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002611
Barry Warsaw53699e91996-12-10 23:23:01 +00002612 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002613 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002614 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002615 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002616 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002617 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002618 u.sysname,
2619 u.nodename,
2620 u.release,
2621 u.version,
2622 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002623}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002624#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002625
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002626static int
2627extract_time(PyObject *t, long* sec, long* usec)
2628{
2629 long intval;
2630 if (PyFloat_Check(t)) {
2631 double tval = PyFloat_AsDouble(t);
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00002632 PyObject *intobj = Py_Type(t)->tp_as_number->nb_int(t);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002633 if (!intobj)
2634 return -1;
2635 intval = PyInt_AsLong(intobj);
2636 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002637 if (intval == -1 && PyErr_Occurred())
2638 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002639 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002640 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002641 if (*usec < 0)
2642 /* If rounding gave us a negative number,
2643 truncate. */
2644 *usec = 0;
2645 return 0;
2646 }
2647 intval = PyInt_AsLong(t);
2648 if (intval == -1 && PyErr_Occurred())
2649 return -1;
2650 *sec = intval;
2651 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002652 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002653}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002654
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002655PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002656"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002657utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002658Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002659second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002660
Barry Warsaw53699e91996-12-10 23:23:01 +00002661static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002662posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002663{
Thomas Wouters477c8d52006-05-27 19:21:47 +00002664#ifdef Py_WIN_WIDE_FILENAMES
2665 PyObject *arg;
2666 PyUnicodeObject *obwpath;
2667 wchar_t *wpath = NULL;
2668 char *apath = NULL;
2669 HANDLE hFile;
2670 long atimesec, mtimesec, ausec, musec;
2671 FILETIME atime, mtime;
2672 PyObject *result = NULL;
2673
2674 if (unicode_file_names()) {
2675 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2676 wpath = PyUnicode_AS_UNICODE(obwpath);
2677 Py_BEGIN_ALLOW_THREADS
2678 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
Thomas Wouters89f507f2006-12-13 04:49:30 +00002679 NULL, OPEN_EXISTING,
2680 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002681 Py_END_ALLOW_THREADS
2682 if (hFile == INVALID_HANDLE_VALUE)
2683 return win32_error_unicode("utime", wpath);
2684 } else
2685 /* Drop the argument parsing error as narrow strings
2686 are also valid. */
2687 PyErr_Clear();
2688 }
2689 if (!wpath) {
2690 if (!PyArg_ParseTuple(args, "etO:utime",
2691 Py_FileSystemDefaultEncoding, &apath, &arg))
2692 return NULL;
2693 Py_BEGIN_ALLOW_THREADS
2694 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
Thomas Wouters89f507f2006-12-13 04:49:30 +00002695 NULL, OPEN_EXISTING,
2696 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002697 Py_END_ALLOW_THREADS
2698 if (hFile == INVALID_HANDLE_VALUE) {
2699 win32_error("utime", apath);
2700 PyMem_Free(apath);
2701 return NULL;
2702 }
2703 PyMem_Free(apath);
2704 }
2705
2706 if (arg == Py_None) {
2707 SYSTEMTIME now;
2708 GetSystemTime(&now);
2709 if (!SystemTimeToFileTime(&now, &mtime) ||
2710 !SystemTimeToFileTime(&now, &atime)) {
2711 win32_error("utime", NULL);
2712 goto done;
2713 }
2714 }
2715 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2716 PyErr_SetString(PyExc_TypeError,
2717 "utime() arg 2 must be a tuple (atime, mtime)");
2718 goto done;
2719 }
2720 else {
2721 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2722 &atimesec, &ausec) == -1)
2723 goto done;
Thomas Wouters89f507f2006-12-13 04:49:30 +00002724 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002725 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2726 &mtimesec, &musec) == -1)
2727 goto done;
Thomas Wouters89f507f2006-12-13 04:49:30 +00002728 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002729 }
2730 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2731 /* Avoid putting the file name into the error here,
2732 as that may confuse the user into believing that
2733 something is wrong with the file, when it also
2734 could be the time stamp that gives a problem. */
2735 win32_error("utime", NULL);
2736 }
2737 Py_INCREF(Py_None);
2738 result = Py_None;
2739done:
2740 CloseHandle(hFile);
2741 return result;
2742#else /* Py_WIN_WIDE_FILENAMES */
2743
Neal Norwitz2adf2102004-06-09 01:46:02 +00002744 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002745 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002746 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002747 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002748
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002749#if defined(HAVE_UTIMES)
2750 struct timeval buf[2];
2751#define ATIME buf[0].tv_sec
2752#define MTIME buf[1].tv_sec
2753#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002754/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002755 struct utimbuf buf;
2756#define ATIME buf.actime
2757#define MTIME buf.modtime
2758#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002759#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002760 time_t buf[2];
2761#define ATIME buf[0]
2762#define MTIME buf[1]
2763#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002764#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002765
Mark Hammond817c9292003-12-03 01:22:38 +00002766
Thomas Wouters477c8d52006-05-27 19:21:47 +00002767 if (!PyArg_ParseTuple(args, "etO:utime",
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002768 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002769 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002770 if (arg == Py_None) {
2771 /* optional time values not given */
2772 Py_BEGIN_ALLOW_THREADS
2773 res = utime(path, NULL);
2774 Py_END_ALLOW_THREADS
2775 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002776 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002777 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002778 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002779 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002780 return NULL;
2781 }
2782 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002783 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002784 &atime, &ausec) == -1) {
2785 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002786 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002787 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002788 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002789 &mtime, &musec) == -1) {
2790 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002791 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002792 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002793 ATIME = atime;
2794 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002795#ifdef HAVE_UTIMES
2796 buf[0].tv_usec = ausec;
2797 buf[1].tv_usec = musec;
2798 Py_BEGIN_ALLOW_THREADS
2799 res = utimes(path, buf);
2800 Py_END_ALLOW_THREADS
2801#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002802 Py_BEGIN_ALLOW_THREADS
2803 res = utime(path, UTIME_ARG);
2804 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002805#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002806 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002807 if (res < 0) {
Neal Norwitz96652712004-06-06 20:40:27 +00002808 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002809 }
Neal Norwitz96652712004-06-06 20:40:27 +00002810 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002811 Py_INCREF(Py_None);
2812 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002813#undef UTIME_ARG
2814#undef ATIME
2815#undef MTIME
Thomas Wouters477c8d52006-05-27 19:21:47 +00002816#endif /* Py_WIN_WIDE_FILENAMES */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002817}
2818
Guido van Rossum85e3b011991-06-03 12:42:10 +00002819
Guido van Rossum3b066191991-06-04 19:40:25 +00002820/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002821
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002822PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002823"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002824Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002825
Barry Warsaw53699e91996-12-10 23:23:01 +00002826static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002827posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002828{
2829 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002830 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002831 return NULL;
2832 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002833 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002834}
2835
Martin v. Löwis114619e2002-10-07 06:44:21 +00002836#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2837static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002838free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002839{
Martin v. Löwis725507b2006-03-07 12:08:51 +00002840 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002841 for (i = 0; i < count; i++)
2842 PyMem_Free(array[i]);
2843 PyMem_DEL(array);
2844}
2845#endif
2846
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002847
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002848#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002849PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002850"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002851Execute an executable path with arguments, replacing current process.\n\
2852\n\
2853 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002854 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002855
Barry Warsaw53699e91996-12-10 23:23:01 +00002856static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002857posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002858{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002859 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002860 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002861 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002862 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002863 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002864
Guido van Rossum89b33251993-10-22 14:26:06 +00002865 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002866 argv is a list or tuple of strings. */
2867
Martin v. Löwis114619e2002-10-07 06:44:21 +00002868 if (!PyArg_ParseTuple(args, "etO:execv",
2869 Py_FileSystemDefaultEncoding,
2870 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002871 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002872 if (PyList_Check(argv)) {
2873 argc = PyList_Size(argv);
2874 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002875 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002876 else if (PyTuple_Check(argv)) {
2877 argc = PyTuple_Size(argv);
2878 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002879 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002880 else {
Fred Drake661ea262000-10-24 19:57:45 +00002881 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002882 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002883 return NULL;
2884 }
Thomas Heller6790d602007-08-30 17:15:14 +00002885 if (argc < 1) {
2886 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
2887 PyMem_Free(path);
2888 return NULL;
2889 }
Guido van Rossum50422b42000-04-26 20:34:28 +00002890
Barry Warsaw53699e91996-12-10 23:23:01 +00002891 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002892 if (argvlist == NULL) {
2893 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002894 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002895 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002896 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002897 if (!PyArg_Parse((*getitem)(argv, i), "et",
2898 Py_FileSystemDefaultEncoding,
2899 &argvlist[i])) {
2900 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002901 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002902 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002903 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002904 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002905
Guido van Rossum85e3b011991-06-03 12:42:10 +00002906 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002907 }
2908 argvlist[argc] = NULL;
2909
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002910 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002911
Guido van Rossum85e3b011991-06-03 12:42:10 +00002912 /* If we get here it's definitely an error */
2913
Martin v. Löwis114619e2002-10-07 06:44:21 +00002914 free_string_array(argvlist, argc);
2915 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002916 return posix_error();
2917}
2918
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002919
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002920PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002921"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002922Execute a path with arguments and environment, replacing current process.\n\
2923\n\
2924 path: path of executable file\n\
2925 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002926 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002927
Barry Warsaw53699e91996-12-10 23:23:01 +00002928static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002929posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002930{
2931 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002932 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002933 char **argvlist;
2934 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002935 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002936 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002937 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002938 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002939
2940 /* execve has three arguments: (path, argv, env), where
2941 argv is a list or tuple of strings and env is a dictionary
2942 like posix.environ. */
2943
Martin v. Löwis114619e2002-10-07 06:44:21 +00002944 if (!PyArg_ParseTuple(args, "etOO:execve",
2945 Py_FileSystemDefaultEncoding,
2946 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002947 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002948 if (PyList_Check(argv)) {
2949 argc = PyList_Size(argv);
2950 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002951 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002952 else if (PyTuple_Check(argv)) {
2953 argc = PyTuple_Size(argv);
2954 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002955 }
2956 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002957 PyErr_SetString(PyExc_TypeError,
2958 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002959 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002960 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002961 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002962 PyErr_SetString(PyExc_TypeError,
2963 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002964 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002965 }
2966
Barry Warsaw53699e91996-12-10 23:23:01 +00002967 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002968 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002969 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002970 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002971 }
2972 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002973 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002974 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002975 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002976 &argvlist[i]))
2977 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002978 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002979 goto fail_1;
2980 }
2981 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002982 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002983 argvlist[argc] = NULL;
2984
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002985 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002986 if (i < 0)
2987 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002988 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002989 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002990 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002991 goto fail_1;
2992 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002993 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002994 keys = PyMapping_Keys(env);
2995 vals = PyMapping_Values(env);
2996 if (!keys || !vals)
2997 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002998 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2999 PyErr_SetString(PyExc_TypeError,
3000 "execve(): env.keys() or env.values() is not a list");
3001 goto fail_2;
3002 }
Tim Peters5aa91602002-01-30 05:46:57 +00003003
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003004 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003005 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003006 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003007
3008 key = PyList_GetItem(keys, pos);
3009 val = PyList_GetItem(vals, pos);
3010 if (!key || !val)
3011 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003012
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003013 if (!PyArg_Parse(
3014 key,
3015 "s;execve() arg 3 contains a non-string key",
3016 &k) ||
3017 !PyArg_Parse(
3018 val,
3019 "s;execve() arg 3 contains a non-string value",
3020 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003021 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003022 goto fail_2;
3023 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003024
3025#if defined(PYOS_OS2)
3026 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3027 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3028#endif
Tim Petersc8996f52001-12-03 20:41:00 +00003029 len = PyString_Size(key) + PyString_Size(val) + 2;
3030 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003031 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003032 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003033 goto fail_2;
3034 }
Tim Petersc8996f52001-12-03 20:41:00 +00003035 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003036 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003037#if defined(PYOS_OS2)
3038 }
3039#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003040 }
3041 envlist[envc] = 0;
3042
3043 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003044
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003045 /* If we get here it's definitely an error */
3046
3047 (void) posix_error();
3048
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003049 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003050 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00003051 PyMem_DEL(envlist[envc]);
3052 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003053 fail_1:
3054 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003055 Py_XDECREF(vals);
3056 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003057 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003058 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003059 return NULL;
3060}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003061#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003062
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003063
Guido van Rossuma1065681999-01-25 23:20:23 +00003064#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003065PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003066"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003067Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003068\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003069 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003070 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003071 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003072
3073static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003074posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003075{
3076 char *path;
3077 PyObject *argv;
3078 char **argvlist;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003079 int mode, i;
3080 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00003081 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003082 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003083
3084 /* spawnv has three arguments: (mode, path, argv), where
3085 argv is a list or tuple of strings. */
3086
Martin v. Löwis114619e2002-10-07 06:44:21 +00003087 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3088 Py_FileSystemDefaultEncoding,
3089 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00003090 return NULL;
3091 if (PyList_Check(argv)) {
3092 argc = PyList_Size(argv);
3093 getitem = PyList_GetItem;
3094 }
3095 else if (PyTuple_Check(argv)) {
3096 argc = PyTuple_Size(argv);
3097 getitem = PyTuple_GetItem;
3098 }
3099 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003100 PyErr_SetString(PyExc_TypeError,
3101 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003102 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003103 return NULL;
3104 }
3105
3106 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003107 if (argvlist == NULL) {
3108 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003109 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003110 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003111 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003112 if (!PyArg_Parse((*getitem)(argv, i), "et",
3113 Py_FileSystemDefaultEncoding,
3114 &argvlist[i])) {
3115 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003116 PyErr_SetString(
3117 PyExc_TypeError,
3118 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003119 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00003120 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003121 }
3122 }
3123 argvlist[argc] = NULL;
3124
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003125#if defined(PYOS_OS2) && defined(PYCC_GCC)
3126 Py_BEGIN_ALLOW_THREADS
3127 spawnval = spawnv(mode, path, argvlist);
3128 Py_END_ALLOW_THREADS
3129#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003130 if (mode == _OLD_P_OVERLAY)
3131 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003132
Tim Peters25059d32001-12-07 20:35:43 +00003133 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003134 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00003135 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003136#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003137
Martin v. Löwis114619e2002-10-07 06:44:21 +00003138 free_string_array(argvlist, argc);
3139 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003140
Fred Drake699f3522000-06-29 21:12:41 +00003141 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003142 return posix_error();
3143 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003144#if SIZEOF_LONG == SIZEOF_VOID_P
3145 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003146#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003147 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003148#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003149}
3150
3151
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003152PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003153"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003154Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003155\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003156 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003157 path: path of executable file\n\
3158 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003159 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003160
3161static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003162posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003163{
3164 char *path;
3165 PyObject *argv, *env;
3166 char **argvlist;
3167 char **envlist;
3168 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003169 int mode, pos, envc;
3170 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00003171 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003172 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00003173 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003174
3175 /* spawnve has four arguments: (mode, path, argv, env), where
3176 argv is a list or tuple of strings and env is a dictionary
3177 like posix.environ. */
3178
Martin v. Löwis114619e2002-10-07 06:44:21 +00003179 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3180 Py_FileSystemDefaultEncoding,
3181 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00003182 return NULL;
3183 if (PyList_Check(argv)) {
3184 argc = PyList_Size(argv);
3185 getitem = PyList_GetItem;
3186 }
3187 else if (PyTuple_Check(argv)) {
3188 argc = PyTuple_Size(argv);
3189 getitem = PyTuple_GetItem;
3190 }
3191 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003192 PyErr_SetString(PyExc_TypeError,
3193 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003194 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003195 }
3196 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003197 PyErr_SetString(PyExc_TypeError,
3198 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003199 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003200 }
3201
3202 argvlist = PyMem_NEW(char *, argc+1);
3203 if (argvlist == NULL) {
3204 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003205 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003206 }
3207 for (i = 0; i < argc; i++) {
3208 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003209 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00003210 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00003211 &argvlist[i]))
3212 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003213 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00003214 goto fail_1;
3215 }
3216 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003217 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00003218 argvlist[argc] = NULL;
3219
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003220 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003221 if (i < 0)
3222 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003223 envlist = PyMem_NEW(char *, i + 1);
3224 if (envlist == NULL) {
3225 PyErr_NoMemory();
3226 goto fail_1;
3227 }
3228 envc = 0;
3229 keys = PyMapping_Keys(env);
3230 vals = PyMapping_Values(env);
3231 if (!keys || !vals)
3232 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003233 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3234 PyErr_SetString(PyExc_TypeError,
3235 "spawnve(): env.keys() or env.values() is not a list");
3236 goto fail_2;
3237 }
Tim Peters5aa91602002-01-30 05:46:57 +00003238
Guido van Rossuma1065681999-01-25 23:20:23 +00003239 for (pos = 0; pos < i; pos++) {
3240 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003241 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003242
3243 key = PyList_GetItem(keys, pos);
3244 val = PyList_GetItem(vals, pos);
3245 if (!key || !val)
3246 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003247
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003248 if (!PyArg_Parse(
3249 key,
3250 "s;spawnve() arg 3 contains a non-string key",
3251 &k) ||
3252 !PyArg_Parse(
3253 val,
3254 "s;spawnve() arg 3 contains a non-string value",
3255 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00003256 {
3257 goto fail_2;
3258 }
Tim Petersc8996f52001-12-03 20:41:00 +00003259 len = PyString_Size(key) + PyString_Size(val) + 2;
3260 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003261 if (p == NULL) {
3262 PyErr_NoMemory();
3263 goto fail_2;
3264 }
Tim Petersc8996f52001-12-03 20:41:00 +00003265 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003266 envlist[envc++] = p;
3267 }
3268 envlist[envc] = 0;
3269
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003270#if defined(PYOS_OS2) && defined(PYCC_GCC)
3271 Py_BEGIN_ALLOW_THREADS
3272 spawnval = spawnve(mode, path, argvlist, envlist);
3273 Py_END_ALLOW_THREADS
3274#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003275 if (mode == _OLD_P_OVERLAY)
3276 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003277
3278 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003279 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003280 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003281#endif
Tim Peters25059d32001-12-07 20:35:43 +00003282
Fred Drake699f3522000-06-29 21:12:41 +00003283 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003284 (void) posix_error();
3285 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003286#if SIZEOF_LONG == SIZEOF_VOID_P
3287 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003288#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003289 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003290#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003291
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003292 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003293 while (--envc >= 0)
3294 PyMem_DEL(envlist[envc]);
3295 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003296 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003297 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003298 Py_XDECREF(vals);
3299 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003300 fail_0:
3301 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003302 return res;
3303}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003304
3305/* OS/2 supports spawnvp & spawnvpe natively */
3306#if defined(PYOS_OS2)
3307PyDoc_STRVAR(posix_spawnvp__doc__,
3308"spawnvp(mode, file, args)\n\n\
3309Execute the program 'file' in a new process, using the environment\n\
3310search path to find the file.\n\
3311\n\
3312 mode: mode of process creation\n\
3313 file: executable file name\n\
3314 args: tuple or list of strings");
3315
3316static PyObject *
3317posix_spawnvp(PyObject *self, PyObject *args)
3318{
3319 char *path;
3320 PyObject *argv;
3321 char **argvlist;
3322 int mode, i, argc;
3323 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003324 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003325
3326 /* spawnvp has three arguments: (mode, path, argv), where
3327 argv is a list or tuple of strings. */
3328
3329 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3330 Py_FileSystemDefaultEncoding,
3331 &path, &argv))
3332 return NULL;
3333 if (PyList_Check(argv)) {
3334 argc = PyList_Size(argv);
3335 getitem = PyList_GetItem;
3336 }
3337 else if (PyTuple_Check(argv)) {
3338 argc = PyTuple_Size(argv);
3339 getitem = PyTuple_GetItem;
3340 }
3341 else {
3342 PyErr_SetString(PyExc_TypeError,
3343 "spawnvp() arg 2 must be a tuple or list");
3344 PyMem_Free(path);
3345 return NULL;
3346 }
3347
3348 argvlist = PyMem_NEW(char *, argc+1);
3349 if (argvlist == NULL) {
3350 PyMem_Free(path);
3351 return PyErr_NoMemory();
3352 }
3353 for (i = 0; i < argc; i++) {
3354 if (!PyArg_Parse((*getitem)(argv, i), "et",
3355 Py_FileSystemDefaultEncoding,
3356 &argvlist[i])) {
3357 free_string_array(argvlist, i);
3358 PyErr_SetString(
3359 PyExc_TypeError,
3360 "spawnvp() arg 2 must contain only strings");
3361 PyMem_Free(path);
3362 return NULL;
3363 }
3364 }
3365 argvlist[argc] = NULL;
3366
3367 Py_BEGIN_ALLOW_THREADS
3368#if defined(PYCC_GCC)
3369 spawnval = spawnvp(mode, path, argvlist);
3370#else
3371 spawnval = _spawnvp(mode, path, argvlist);
3372#endif
3373 Py_END_ALLOW_THREADS
3374
3375 free_string_array(argvlist, argc);
3376 PyMem_Free(path);
3377
3378 if (spawnval == -1)
3379 return posix_error();
3380 else
3381 return Py_BuildValue("l", (long) spawnval);
3382}
3383
3384
3385PyDoc_STRVAR(posix_spawnvpe__doc__,
3386"spawnvpe(mode, file, args, env)\n\n\
3387Execute the program 'file' in a new process, using the environment\n\
3388search path to find the file.\n\
3389\n\
3390 mode: mode of process creation\n\
3391 file: executable file name\n\
3392 args: tuple or list of arguments\n\
3393 env: dictionary of strings mapping to strings");
3394
3395static PyObject *
3396posix_spawnvpe(PyObject *self, PyObject *args)
3397{
3398 char *path;
3399 PyObject *argv, *env;
3400 char **argvlist;
3401 char **envlist;
3402 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3403 int mode, i, pos, argc, envc;
3404 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003405 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003406 int lastarg = 0;
3407
3408 /* spawnvpe has four arguments: (mode, path, argv, env), where
3409 argv is a list or tuple of strings and env is a dictionary
3410 like posix.environ. */
3411
3412 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3413 Py_FileSystemDefaultEncoding,
3414 &path, &argv, &env))
3415 return NULL;
3416 if (PyList_Check(argv)) {
3417 argc = PyList_Size(argv);
3418 getitem = PyList_GetItem;
3419 }
3420 else if (PyTuple_Check(argv)) {
3421 argc = PyTuple_Size(argv);
3422 getitem = PyTuple_GetItem;
3423 }
3424 else {
3425 PyErr_SetString(PyExc_TypeError,
3426 "spawnvpe() arg 2 must be a tuple or list");
3427 goto fail_0;
3428 }
3429 if (!PyMapping_Check(env)) {
3430 PyErr_SetString(PyExc_TypeError,
3431 "spawnvpe() arg 3 must be a mapping object");
3432 goto fail_0;
3433 }
3434
3435 argvlist = PyMem_NEW(char *, argc+1);
3436 if (argvlist == NULL) {
3437 PyErr_NoMemory();
3438 goto fail_0;
3439 }
3440 for (i = 0; i < argc; i++) {
3441 if (!PyArg_Parse((*getitem)(argv, i),
3442 "et;spawnvpe() arg 2 must contain only strings",
3443 Py_FileSystemDefaultEncoding,
3444 &argvlist[i]))
3445 {
3446 lastarg = i;
3447 goto fail_1;
3448 }
3449 }
3450 lastarg = argc;
3451 argvlist[argc] = NULL;
3452
3453 i = PyMapping_Size(env);
3454 if (i < 0)
3455 goto fail_1;
3456 envlist = PyMem_NEW(char *, i + 1);
3457 if (envlist == NULL) {
3458 PyErr_NoMemory();
3459 goto fail_1;
3460 }
3461 envc = 0;
3462 keys = PyMapping_Keys(env);
3463 vals = PyMapping_Values(env);
3464 if (!keys || !vals)
3465 goto fail_2;
3466 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3467 PyErr_SetString(PyExc_TypeError,
3468 "spawnvpe(): env.keys() or env.values() is not a list");
3469 goto fail_2;
3470 }
3471
3472 for (pos = 0; pos < i; pos++) {
3473 char *p, *k, *v;
3474 size_t len;
3475
3476 key = PyList_GetItem(keys, pos);
3477 val = PyList_GetItem(vals, pos);
3478 if (!key || !val)
3479 goto fail_2;
3480
3481 if (!PyArg_Parse(
3482 key,
3483 "s;spawnvpe() arg 3 contains a non-string key",
3484 &k) ||
3485 !PyArg_Parse(
3486 val,
3487 "s;spawnvpe() arg 3 contains a non-string value",
3488 &v))
3489 {
3490 goto fail_2;
3491 }
3492 len = PyString_Size(key) + PyString_Size(val) + 2;
3493 p = PyMem_NEW(char, len);
3494 if (p == NULL) {
3495 PyErr_NoMemory();
3496 goto fail_2;
3497 }
3498 PyOS_snprintf(p, len, "%s=%s", k, v);
3499 envlist[envc++] = p;
3500 }
3501 envlist[envc] = 0;
3502
3503 Py_BEGIN_ALLOW_THREADS
3504#if defined(PYCC_GCC)
3505 spawnval = spawnve(mode, path, argvlist, envlist);
3506#else
3507 spawnval = _spawnve(mode, path, argvlist, envlist);
3508#endif
3509 Py_END_ALLOW_THREADS
3510
3511 if (spawnval == -1)
3512 (void) posix_error();
3513 else
3514 res = Py_BuildValue("l", (long) spawnval);
3515
3516 fail_2:
3517 while (--envc >= 0)
3518 PyMem_DEL(envlist[envc]);
3519 PyMem_DEL(envlist);
3520 fail_1:
3521 free_string_array(argvlist, lastarg);
3522 Py_XDECREF(vals);
3523 Py_XDECREF(keys);
3524 fail_0:
3525 PyMem_Free(path);
3526 return res;
3527}
3528#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003529#endif /* HAVE_SPAWNV */
3530
3531
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003532#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003533PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003534"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003535Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3536\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003537Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003538
3539static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003540posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003541{
Neal Norwitze241ce82003-02-17 18:17:05 +00003542 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003543 if (pid == -1)
3544 return posix_error();
3545 PyOS_AfterFork();
3546 return PyInt_FromLong((long)pid);
3547}
3548#endif
3549
3550
Guido van Rossumad0ee831995-03-01 10:34:45 +00003551#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003552PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003553"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003554Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003555Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003556
Barry Warsaw53699e91996-12-10 23:23:01 +00003557static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003558posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003559{
Neal Norwitze241ce82003-02-17 18:17:05 +00003560 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003561 if (pid == -1)
3562 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003563 if (pid == 0)
3564 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00003565 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003566}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003567#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003568
Neal Norwitzb59798b2003-03-21 01:43:31 +00003569/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003570/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3571#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003572#define DEV_PTY_FILE "/dev/ptc"
3573#define HAVE_DEV_PTMX
3574#else
3575#define DEV_PTY_FILE "/dev/ptmx"
3576#endif
3577
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003578#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003579#ifdef HAVE_PTY_H
3580#include <pty.h>
3581#else
3582#ifdef HAVE_LIBUTIL_H
3583#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003584#endif /* HAVE_LIBUTIL_H */
3585#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003586#ifdef HAVE_STROPTS_H
3587#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003588#endif
3589#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003590
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003591#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003592PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003593"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003594Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003595
3596static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003597posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003598{
3599 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003600#ifndef HAVE_OPENPTY
3601 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003602#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003603#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003604 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003605#ifdef sun
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003606 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003607#endif
3608#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003609
Thomas Wouters70c21a12000-07-14 14:28:33 +00003610#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003611 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3612 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003613#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003614 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3615 if (slave_name == NULL)
3616 return posix_error();
3617
3618 slave_fd = open(slave_name, O_RDWR);
3619 if (slave_fd < 0)
3620 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003621#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003622 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003623 if (master_fd < 0)
3624 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003625 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003626 /* change permission of slave */
3627 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003628 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003629 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003630 }
3631 /* unlock slave */
3632 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003633 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003634 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003635 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003636 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003637 slave_name = ptsname(master_fd); /* get name of slave */
3638 if (slave_name == NULL)
3639 return posix_error();
3640 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3641 if (slave_fd < 0)
3642 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003643#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003644 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3645 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003646#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003647 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003648#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003649#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003650#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003651
Fred Drake8cef4cf2000-06-28 16:40:38 +00003652 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003653
Fred Drake8cef4cf2000-06-28 16:40:38 +00003654}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003655#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003656
3657#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003658PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003659"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003660Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3661Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003662To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003663
3664static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003665posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003666{
Neal Norwitz24b3c222005-09-19 06:43:44 +00003667 int master_fd = -1, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003668
Fred Drake8cef4cf2000-06-28 16:40:38 +00003669 pid = forkpty(&master_fd, NULL, NULL, NULL);
3670 if (pid == -1)
3671 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003672 if (pid == 0)
3673 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00003674 return Py_BuildValue("(ii)", pid, master_fd);
3675}
3676#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003677
Guido van Rossumad0ee831995-03-01 10:34:45 +00003678#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003679PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003680"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003681Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003682
Barry Warsaw53699e91996-12-10 23:23:01 +00003683static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003684posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003685{
Barry Warsaw53699e91996-12-10 23:23:01 +00003686 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003687}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003688#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003689
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003690
Guido van Rossumad0ee831995-03-01 10:34:45 +00003691#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003692PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003693"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003694Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003695
Barry Warsaw53699e91996-12-10 23:23:01 +00003696static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003697posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003698{
Barry Warsaw53699e91996-12-10 23:23:01 +00003699 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003700}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003701#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003702
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003703
Guido van Rossumad0ee831995-03-01 10:34:45 +00003704#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003705PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003706"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003707Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003708
Barry Warsaw53699e91996-12-10 23:23:01 +00003709static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003710posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003711{
Barry Warsaw53699e91996-12-10 23:23:01 +00003712 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003713}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003714#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003715
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003716
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003717PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003718"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003719Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003720
Barry Warsaw53699e91996-12-10 23:23:01 +00003721static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003722posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003723{
Barry Warsaw53699e91996-12-10 23:23:01 +00003724 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003725}
3726
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003727
Fred Drakec9680921999-12-13 16:37:25 +00003728#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003729PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003730"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003731Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003732
3733static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003734posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003735{
3736 PyObject *result = NULL;
3737
Fred Drakec9680921999-12-13 16:37:25 +00003738#ifdef NGROUPS_MAX
3739#define MAX_GROUPS NGROUPS_MAX
3740#else
3741 /* defined to be 16 on Solaris7, so this should be a small number */
3742#define MAX_GROUPS 64
3743#endif
3744 gid_t grouplist[MAX_GROUPS];
3745 int n;
3746
3747 n = getgroups(MAX_GROUPS, grouplist);
3748 if (n < 0)
3749 posix_error();
3750 else {
3751 result = PyList_New(n);
3752 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003753 int i;
3754 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003755 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003756 if (o == NULL) {
3757 Py_DECREF(result);
3758 result = NULL;
3759 break;
3760 }
3761 PyList_SET_ITEM(result, i, o);
3762 }
3763 }
3764 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003765
Fred Drakec9680921999-12-13 16:37:25 +00003766 return result;
3767}
3768#endif
3769
Martin v. Löwis606edc12002-06-13 21:09:11 +00003770#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003771PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003772"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003773Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003774
3775static PyObject *
3776posix_getpgid(PyObject *self, PyObject *args)
3777{
3778 int pid, pgid;
3779 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3780 return NULL;
3781 pgid = getpgid(pid);
3782 if (pgid < 0)
3783 return posix_error();
3784 return PyInt_FromLong((long)pgid);
3785}
3786#endif /* HAVE_GETPGID */
3787
3788
Guido van Rossumb6775db1994-08-01 11:34:53 +00003789#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003790PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003791"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003792Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003793
Barry Warsaw53699e91996-12-10 23:23:01 +00003794static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003795posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003796{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003797#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003798 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003799#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003800 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003801#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003802}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003803#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003804
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003805
Guido van Rossumb6775db1994-08-01 11:34:53 +00003806#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003807PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003808"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003809Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003810
Barry Warsaw53699e91996-12-10 23:23:01 +00003811static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003812posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003813{
Guido van Rossum64933891994-10-20 21:56:42 +00003814#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003815 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003816#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003817 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003818#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003819 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003820 Py_INCREF(Py_None);
3821 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003822}
3823
Guido van Rossumb6775db1994-08-01 11:34:53 +00003824#endif /* HAVE_SETPGRP */
3825
Guido van Rossumad0ee831995-03-01 10:34:45 +00003826#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003827PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003828"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003829Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003830
Barry Warsaw53699e91996-12-10 23:23:01 +00003831static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003832posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003833{
Barry Warsaw53699e91996-12-10 23:23:01 +00003834 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003835}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003836#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003837
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003838
Fred Drake12c6e2d1999-12-14 21:25:03 +00003839#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003840PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003841"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003842Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003843
3844static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003845posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003846{
Neal Norwitze241ce82003-02-17 18:17:05 +00003847 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003848 char *name;
3849 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003850
Fred Drakea30680b2000-12-06 21:24:28 +00003851 errno = 0;
3852 name = getlogin();
3853 if (name == NULL) {
3854 if (errno)
3855 posix_error();
3856 else
3857 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003858 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003859 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003860 else
Neal Norwitz93c56822007-08-26 07:10:06 +00003861 result = PyUnicode_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003862 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003863
Fred Drake12c6e2d1999-12-14 21:25:03 +00003864 return result;
3865}
3866#endif
3867
Guido van Rossumad0ee831995-03-01 10:34:45 +00003868#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003869PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003870"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003871Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003872
Barry Warsaw53699e91996-12-10 23:23:01 +00003873static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003874posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003875{
Barry Warsaw53699e91996-12-10 23:23:01 +00003876 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003877}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003878#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003879
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003880
Guido van Rossumad0ee831995-03-01 10:34:45 +00003881#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003882PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003883"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003884Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003885
Barry Warsaw53699e91996-12-10 23:23:01 +00003886static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003887posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003888{
3889 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003890 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003891 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003892#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003893 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3894 APIRET rc;
3895 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003896 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003897
3898 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3899 APIRET rc;
3900 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003901 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003902
3903 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003904 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003905#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003906 if (kill(pid, sig) == -1)
3907 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003908#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003909 Py_INCREF(Py_None);
3910 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003911}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003912#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003913
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003914#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003915PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003916"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003917Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003918
3919static PyObject *
3920posix_killpg(PyObject *self, PyObject *args)
3921{
3922 int pgid, sig;
3923 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3924 return NULL;
3925 if (killpg(pgid, sig) == -1)
3926 return posix_error();
3927 Py_INCREF(Py_None);
3928 return Py_None;
3929}
3930#endif
3931
Guido van Rossumc0125471996-06-28 18:55:32 +00003932#ifdef HAVE_PLOCK
3933
3934#ifdef HAVE_SYS_LOCK_H
3935#include <sys/lock.h>
3936#endif
3937
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003938PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003939"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003940Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003941
Barry Warsaw53699e91996-12-10 23:23:01 +00003942static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003943posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003944{
3945 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003946 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003947 return NULL;
3948 if (plock(op) == -1)
3949 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003950 Py_INCREF(Py_None);
3951 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003952}
3953#endif
3954
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003955
Guido van Rossum3b066191991-06-04 19:40:25 +00003956
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003957
Guido van Rossumb6775db1994-08-01 11:34:53 +00003958#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003959PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003960"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003961Set the current process's user id.");
3962
Barry Warsaw53699e91996-12-10 23:23:01 +00003963static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003964posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003965{
3966 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003967 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003968 return NULL;
3969 if (setuid(uid) < 0)
3970 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003971 Py_INCREF(Py_None);
3972 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003973}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003974#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003975
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003976
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003977#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003978PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003979"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003980Set the current process's effective user id.");
3981
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003982static PyObject *
3983posix_seteuid (PyObject *self, PyObject *args)
3984{
3985 int euid;
3986 if (!PyArg_ParseTuple(args, "i", &euid)) {
3987 return NULL;
3988 } else if (seteuid(euid) < 0) {
3989 return posix_error();
3990 } else {
3991 Py_INCREF(Py_None);
3992 return Py_None;
3993 }
3994}
3995#endif /* HAVE_SETEUID */
3996
3997#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003998PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003999"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004000Set the current process's effective group id.");
4001
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004002static PyObject *
4003posix_setegid (PyObject *self, PyObject *args)
4004{
4005 int egid;
4006 if (!PyArg_ParseTuple(args, "i", &egid)) {
4007 return NULL;
4008 } else if (setegid(egid) < 0) {
4009 return posix_error();
4010 } else {
4011 Py_INCREF(Py_None);
4012 return Py_None;
4013 }
4014}
4015#endif /* HAVE_SETEGID */
4016
4017#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004018PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004019"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004020Set the current process's real and effective user ids.");
4021
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004022static PyObject *
4023posix_setreuid (PyObject *self, PyObject *args)
4024{
4025 int ruid, euid;
4026 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4027 return NULL;
4028 } else if (setreuid(ruid, euid) < 0) {
4029 return posix_error();
4030 } else {
4031 Py_INCREF(Py_None);
4032 return Py_None;
4033 }
4034}
4035#endif /* HAVE_SETREUID */
4036
4037#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004038PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004039"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004040Set the current process's real and effective group ids.");
4041
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004042static PyObject *
4043posix_setregid (PyObject *self, PyObject *args)
4044{
4045 int rgid, egid;
4046 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4047 return NULL;
4048 } else if (setregid(rgid, egid) < 0) {
4049 return posix_error();
4050 } else {
4051 Py_INCREF(Py_None);
4052 return Py_None;
4053 }
4054}
4055#endif /* HAVE_SETREGID */
4056
Guido van Rossumb6775db1994-08-01 11:34:53 +00004057#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004058PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004059"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004060Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004061
Barry Warsaw53699e91996-12-10 23:23:01 +00004062static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004063posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004064{
4065 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004066 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004067 return NULL;
4068 if (setgid(gid) < 0)
4069 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004070 Py_INCREF(Py_None);
4071 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004072}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004073#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004074
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004075#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004076PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004077"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004078Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004079
4080static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004081posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004082{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004083 int i, len;
4084 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004085
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004086 if (!PySequence_Check(groups)) {
4087 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4088 return NULL;
4089 }
4090 len = PySequence_Size(groups);
4091 if (len > MAX_GROUPS) {
4092 PyErr_SetString(PyExc_ValueError, "too many groups");
4093 return NULL;
4094 }
4095 for(i = 0; i < len; i++) {
4096 PyObject *elem;
4097 elem = PySequence_GetItem(groups, i);
4098 if (!elem)
4099 return NULL;
Guido van Rossumddefaf32007-01-14 03:31:43 +00004100 if (!PyLong_Check(elem)) {
4101 PyErr_SetString(PyExc_TypeError,
4102 "groups must be integers");
4103 Py_DECREF(elem);
4104 return NULL;
4105 } else {
4106 unsigned long x = PyLong_AsUnsignedLong(elem);
4107 if (PyErr_Occurred()) {
4108 PyErr_SetString(PyExc_TypeError,
4109 "group id too big");
Georg Brandla13c2442005-11-22 19:30:31 +00004110 Py_DECREF(elem);
4111 return NULL;
Georg Brandla13c2442005-11-22 19:30:31 +00004112 }
Georg Brandla13c2442005-11-22 19:30:31 +00004113 grouplist[i] = x;
Guido van Rossumddefaf32007-01-14 03:31:43 +00004114 /* read back the value to see if it fitted in gid_t */
Georg Brandla13c2442005-11-22 19:30:31 +00004115 if (grouplist[i] != x) {
4116 PyErr_SetString(PyExc_TypeError,
4117 "group id too big");
4118 Py_DECREF(elem);
4119 return NULL;
4120 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004121 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004122 Py_DECREF(elem);
4123 }
4124
4125 if (setgroups(len, grouplist) < 0)
4126 return posix_error();
4127 Py_INCREF(Py_None);
4128 return Py_None;
4129}
4130#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004131
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004132#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4133static PyObject *
4134wait_helper(int pid, int status, struct rusage *ru)
4135{
4136 PyObject *result;
4137 static PyObject *struct_rusage;
4138
4139 if (pid == -1)
4140 return posix_error();
4141
4142 if (struct_rusage == NULL) {
4143 PyObject *m = PyImport_ImportModule("resource");
4144 if (m == NULL)
4145 return NULL;
4146 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4147 Py_DECREF(m);
4148 if (struct_rusage == NULL)
4149 return NULL;
4150 }
4151
4152 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4153 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4154 if (!result)
4155 return NULL;
4156
4157#ifndef doubletime
4158#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4159#endif
4160
4161 PyStructSequence_SET_ITEM(result, 0,
4162 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4163 PyStructSequence_SET_ITEM(result, 1,
4164 PyFloat_FromDouble(doubletime(ru->ru_stime)));
4165#define SET_INT(result, index, value)\
4166 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
4167 SET_INT(result, 2, ru->ru_maxrss);
4168 SET_INT(result, 3, ru->ru_ixrss);
4169 SET_INT(result, 4, ru->ru_idrss);
4170 SET_INT(result, 5, ru->ru_isrss);
4171 SET_INT(result, 6, ru->ru_minflt);
4172 SET_INT(result, 7, ru->ru_majflt);
4173 SET_INT(result, 8, ru->ru_nswap);
4174 SET_INT(result, 9, ru->ru_inblock);
4175 SET_INT(result, 10, ru->ru_oublock);
4176 SET_INT(result, 11, ru->ru_msgsnd);
4177 SET_INT(result, 12, ru->ru_msgrcv);
4178 SET_INT(result, 13, ru->ru_nsignals);
4179 SET_INT(result, 14, ru->ru_nvcsw);
4180 SET_INT(result, 15, ru->ru_nivcsw);
4181#undef SET_INT
4182
4183 if (PyErr_Occurred()) {
4184 Py_DECREF(result);
4185 return NULL;
4186 }
4187
4188 return Py_BuildValue("iiN", pid, status, result);
4189}
4190#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4191
4192#ifdef HAVE_WAIT3
4193PyDoc_STRVAR(posix_wait3__doc__,
4194"wait3(options) -> (pid, status, rusage)\n\n\
4195Wait for completion of a child process.");
4196
4197static PyObject *
4198posix_wait3(PyObject *self, PyObject *args)
4199{
4200 int pid, options;
4201 struct rusage ru;
4202 WAIT_TYPE status;
4203 WAIT_STATUS_INT(status) = 0;
4204
4205 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4206 return NULL;
4207
4208 Py_BEGIN_ALLOW_THREADS
4209 pid = wait3(&status, options, &ru);
4210 Py_END_ALLOW_THREADS
4211
4212 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
4213}
4214#endif /* HAVE_WAIT3 */
4215
4216#ifdef HAVE_WAIT4
4217PyDoc_STRVAR(posix_wait4__doc__,
4218"wait4(pid, options) -> (pid, status, rusage)\n\n\
4219Wait for completion of a given child process.");
4220
4221static PyObject *
4222posix_wait4(PyObject *self, PyObject *args)
4223{
4224 int pid, options;
4225 struct rusage ru;
4226 WAIT_TYPE status;
4227 WAIT_STATUS_INT(status) = 0;
4228
4229 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
4230 return NULL;
4231
4232 Py_BEGIN_ALLOW_THREADS
4233 pid = wait4(pid, &status, options, &ru);
4234 Py_END_ALLOW_THREADS
4235
4236 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
4237}
4238#endif /* HAVE_WAIT4 */
4239
Guido van Rossumb6775db1994-08-01 11:34:53 +00004240#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004241PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004242"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004243Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004244
Barry Warsaw53699e91996-12-10 23:23:01 +00004245static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004246posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004247{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004248 int pid, options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004249 WAIT_TYPE status;
4250 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004251
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004252 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004253 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004254 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004255 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004256 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004257 if (pid == -1)
4258 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004259
4260 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00004261}
4262
Tim Petersab034fa2002-02-01 11:27:43 +00004263#elif defined(HAVE_CWAIT)
4264
4265/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004266PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004267"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004268"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004269
4270static PyObject *
4271posix_waitpid(PyObject *self, PyObject *args)
4272{
Thomas Wouters477c8d52006-05-27 19:21:47 +00004273 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004274 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00004275
4276 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4277 return NULL;
4278 Py_BEGIN_ALLOW_THREADS
4279 pid = _cwait(&status, pid, options);
4280 Py_END_ALLOW_THREADS
4281 if (pid == -1)
4282 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004283
4284 /* shift the status left a byte so this is more like the POSIX waitpid */
4285 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00004286}
4287#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004288
Guido van Rossumad0ee831995-03-01 10:34:45 +00004289#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004290PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004291"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004292Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004293
Barry Warsaw53699e91996-12-10 23:23:01 +00004294static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004295posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004296{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004297 int pid;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004298 WAIT_TYPE status;
4299 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00004300
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004301 Py_BEGIN_ALLOW_THREADS
4302 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004303 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004304 if (pid == -1)
4305 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004306
4307 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00004308}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004309#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004310
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004311
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004312PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004313"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004314Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004315
Barry Warsaw53699e91996-12-10 23:23:01 +00004316static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004317posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004318{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004319#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004320 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004321#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004322#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00004323 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004324#else
4325 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4326#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004327#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004328}
4329
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004330
Guido van Rossumb6775db1994-08-01 11:34:53 +00004331#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004332PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004333"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004334Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004335
Barry Warsaw53699e91996-12-10 23:23:01 +00004336static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004337posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004338{
Thomas Wouters89f507f2006-12-13 04:49:30 +00004339 PyObject* v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00004340 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004341 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004342 int n;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004343 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004344
4345 if (!PyArg_ParseTuple(args, "et:readlink",
4346 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004347 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004348 v = PySequence_GetItem(args, 0);
Neal Norwitzcda5c062007-08-12 17:09:36 +00004349 if (v == NULL) {
4350 PyMem_Free(path);
4351 return NULL;
4352 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00004353
4354 if (PyUnicode_Check(v)) {
4355 arg_is_unicode = 1;
4356 }
4357 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004358
Barry Warsaw53699e91996-12-10 23:23:01 +00004359 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004360 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004361 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004362 if (n < 0)
Neal Norwitzfca70052007-08-12 16:56:02 +00004363 return posix_error_with_allocated_filename(path);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004364
Neal Norwitzfca70052007-08-12 16:56:02 +00004365 PyMem_Free(path);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004366 v = PyString_FromStringAndSize(buf, n);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004367 if (arg_is_unicode) {
4368 PyObject *w;
4369
4370 w = PyUnicode_FromEncodedObject(v,
4371 Py_FileSystemDefaultEncoding,
4372 "strict");
4373 if (w != NULL) {
4374 Py_DECREF(v);
4375 v = w;
4376 }
4377 else {
4378 /* fall back to the original byte string, as
4379 discussed in patch #683592 */
4380 PyErr_Clear();
4381 }
4382 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00004383 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004384}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004385#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004386
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004387
Guido van Rossumb6775db1994-08-01 11:34:53 +00004388#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004389PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004390"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00004391Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004392
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004393static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004394posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004395{
Thomas Wouters477c8d52006-05-27 19:21:47 +00004396 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004397}
4398#endif /* HAVE_SYMLINK */
4399
4400
4401#ifdef HAVE_TIMES
4402#ifndef HZ
4403#define HZ 60 /* Universal constant :-) */
4404#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004405
Guido van Rossumd48f2521997-12-05 22:19:34 +00004406#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4407static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004408system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004409{
4410 ULONG value = 0;
4411
4412 Py_BEGIN_ALLOW_THREADS
4413 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4414 Py_END_ALLOW_THREADS
4415
4416 return value;
4417}
4418
4419static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004420posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004421{
Guido van Rossumd48f2521997-12-05 22:19:34 +00004422 /* Currently Only Uptime is Provided -- Others Later */
4423 return Py_BuildValue("ddddd",
4424 (double)0 /* t.tms_utime / HZ */,
4425 (double)0 /* t.tms_stime / HZ */,
4426 (double)0 /* t.tms_cutime / HZ */,
4427 (double)0 /* t.tms_cstime / HZ */,
4428 (double)system_uptime() / 1000);
4429}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004430#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004431static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004432posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004433{
4434 struct tms t;
4435 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00004436 errno = 0;
4437 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004438 if (c == (clock_t) -1)
4439 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004440 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004441 (double)t.tms_utime / HZ,
4442 (double)t.tms_stime / HZ,
4443 (double)t.tms_cutime / HZ,
4444 (double)t.tms_cstime / HZ,
4445 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004446}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004447#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004448#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004449
4450
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004451#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004452#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004453static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004454posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004455{
4456 FILETIME create, exit, kernel, user;
4457 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004458 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004459 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4460 /* The fields of a FILETIME structure are the hi and lo part
4461 of a 64-bit value expressed in 100 nanosecond units.
4462 1e7 is one second in such units; 1e-7 the inverse.
4463 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4464 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004465 return Py_BuildValue(
4466 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004467 (double)(kernel.dwHighDateTime*429.4967296 +
4468 kernel.dwLowDateTime*1e-7),
4469 (double)(user.dwHighDateTime*429.4967296 +
4470 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004471 (double)0,
4472 (double)0,
4473 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004474}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004475#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004476
4477#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004478PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004479"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004480Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004481#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004482
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004483
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004484#ifdef HAVE_GETSID
4485PyDoc_STRVAR(posix_getsid__doc__,
4486"getsid(pid) -> sid\n\n\
4487Call the system call getsid().");
4488
4489static PyObject *
4490posix_getsid(PyObject *self, PyObject *args)
4491{
4492 int pid, sid;
4493 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
4494 return NULL;
4495 sid = getsid(pid);
4496 if (sid < 0)
4497 return posix_error();
4498 return PyInt_FromLong((long)sid);
4499}
4500#endif /* HAVE_GETSID */
4501
4502
Guido van Rossumb6775db1994-08-01 11:34:53 +00004503#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004504PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004505"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004506Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004507
Barry Warsaw53699e91996-12-10 23:23:01 +00004508static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004509posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004510{
Guido van Rossum687dd131993-05-17 08:34:16 +00004511 if (setsid() < 0)
4512 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004513 Py_INCREF(Py_None);
4514 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004515}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004516#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004517
Guido van Rossumb6775db1994-08-01 11:34:53 +00004518#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004519PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004520"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004521Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004522
Barry Warsaw53699e91996-12-10 23:23:01 +00004523static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004524posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004525{
4526 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004527 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004528 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004529 if (setpgid(pid, pgrp) < 0)
4530 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004531 Py_INCREF(Py_None);
4532 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004533}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004534#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004535
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004536
Guido van Rossumb6775db1994-08-01 11:34:53 +00004537#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004538PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004539"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004540Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004541
Barry Warsaw53699e91996-12-10 23:23:01 +00004542static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004543posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004544{
4545 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004546 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004547 return NULL;
4548 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004549 if (pgid < 0)
4550 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004551 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004552}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004553#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004554
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004555
Guido van Rossumb6775db1994-08-01 11:34:53 +00004556#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004557PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004558"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004559Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004560
Barry Warsaw53699e91996-12-10 23:23:01 +00004561static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004562posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004563{
4564 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004565 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004566 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004567 if (tcsetpgrp(fd, pgid) < 0)
4568 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004569 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004570 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004571}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004572#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004573
Guido van Rossum687dd131993-05-17 08:34:16 +00004574/* Functions acting on file descriptors */
4575
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004576PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004577"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004578Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004579
Barry Warsaw53699e91996-12-10 23:23:01 +00004580static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004581posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004582{
Mark Hammondef8b6542001-05-13 08:04:26 +00004583 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004584 int flag;
4585 int mode = 0777;
4586 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004587
4588#ifdef MS_WINDOWS
4589 if (unicode_file_names()) {
4590 PyUnicodeObject *po;
4591 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4592 Py_BEGIN_ALLOW_THREADS
4593 /* PyUnicode_AS_UNICODE OK without thread
4594 lock as it is a simple dereference. */
4595 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4596 Py_END_ALLOW_THREADS
4597 if (fd < 0)
4598 return posix_error();
4599 return PyInt_FromLong((long)fd);
4600 }
4601 /* Drop the argument parsing error as narrow strings
4602 are also valid. */
4603 PyErr_Clear();
4604 }
4605#endif
4606
Tim Peters5aa91602002-01-30 05:46:57 +00004607 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004608 Py_FileSystemDefaultEncoding, &file,
4609 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004610 return NULL;
4611
Barry Warsaw53699e91996-12-10 23:23:01 +00004612 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004613 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004614 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004615 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004616 return posix_error_with_allocated_filename(file);
4617 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004618 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004619}
4620
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004621
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004622PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004623"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004624Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004625
Barry Warsaw53699e91996-12-10 23:23:01 +00004626static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004627posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004628{
4629 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004630 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004631 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004632 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004633 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004634 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004635 if (res < 0)
4636 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004637 Py_INCREF(Py_None);
4638 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004639}
4640
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004641
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004642PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004643"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004644Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004645
Barry Warsaw53699e91996-12-10 23:23:01 +00004646static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004647posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004648{
4649 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004650 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004651 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004652 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004653 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004654 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004655 if (fd < 0)
4656 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004657 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004658}
4659
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004660
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004661PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00004662"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004663Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004664
Barry Warsaw53699e91996-12-10 23:23:01 +00004665static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004666posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004667{
4668 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004669 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004670 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004671 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004672 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004673 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004674 if (res < 0)
4675 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004676 Py_INCREF(Py_None);
4677 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004678}
4679
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004680
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004681PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004682"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004683Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004684
Barry Warsaw53699e91996-12-10 23:23:01 +00004685static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004686posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004687{
4688 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004689#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00004690 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004691#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004692 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004693#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004694 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004695 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004696 return NULL;
4697#ifdef SEEK_SET
4698 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4699 switch (how) {
4700 case 0: how = SEEK_SET; break;
4701 case 1: how = SEEK_CUR; break;
4702 case 2: how = SEEK_END; break;
4703 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004704#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004705
4706#if !defined(HAVE_LARGEFILE_SUPPORT)
4707 pos = PyInt_AsLong(posobj);
4708#else
4709 pos = PyLong_Check(posobj) ?
4710 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4711#endif
4712 if (PyErr_Occurred())
4713 return NULL;
4714
Barry Warsaw53699e91996-12-10 23:23:01 +00004715 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004716#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004717 res = _lseeki64(fd, pos, how);
4718#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004719 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004720#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004721 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004722 if (res < 0)
4723 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004724
4725#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00004726 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004727#else
4728 return PyLong_FromLongLong(res);
4729#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004730}
4731
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004732
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004733PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004734"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004735Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004736
Barry Warsaw53699e91996-12-10 23:23:01 +00004737static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004738posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004739{
Guido van Rossum572dbf82007-04-27 23:53:51 +00004740 int fd, size;
4741 Py_ssize_t n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004742 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004743 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004744 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00004745 if (size < 0) {
4746 errno = EINVAL;
4747 return posix_error();
4748 }
Guido van Rossumf9e443c2007-11-21 20:17:11 +00004749 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004750 if (buffer == NULL)
4751 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004752 Py_BEGIN_ALLOW_THREADS
Guido van Rossumf9e443c2007-11-21 20:17:11 +00004753 n = read(fd, PyString_AS_STRING(buffer), size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004754 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004755 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004756 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004757 return posix_error();
4758 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004759 if (n != size)
Guido van Rossumf9e443c2007-11-21 20:17:11 +00004760 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004761 return buffer;
4762}
4763
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004764
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004765PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004766"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004767Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004768
Barry Warsaw53699e91996-12-10 23:23:01 +00004769static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004770posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004771{
Thomas Wouters68bc4f92006-03-01 01:05:10 +00004772 int fd;
4773 Py_ssize_t size;
Guido van Rossum687dd131993-05-17 08:34:16 +00004774 char *buffer;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00004775
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004776 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004777 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004778 Py_BEGIN_ALLOW_THREADS
Thomas Wouters68bc4f92006-03-01 01:05:10 +00004779 size = write(fd, buffer, (size_t)size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004780 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004781 if (size < 0)
4782 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00004783 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004784}
4785
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004786
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004787PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004788"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004789Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004790
Barry Warsaw53699e91996-12-10 23:23:01 +00004791static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004792posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004793{
4794 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00004795 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00004796 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004797 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004798 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00004799#ifdef __VMS
4800 /* on OpenVMS we must ensure that all bytes are written to the file */
4801 fsync(fd);
4802#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004803 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00004804 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00004805 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00004806 if (res != 0) {
4807#ifdef MS_WINDOWS
4808 return win32_error("fstat", NULL);
4809#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004810 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00004811#endif
4812 }
Tim Peters5aa91602002-01-30 05:46:57 +00004813
Martin v. Löwis14694662006-02-03 12:54:16 +00004814 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00004815}
4816
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004817PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004818"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00004819Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004820connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00004821
4822static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00004823posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00004824{
4825 int fd;
4826 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
4827 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00004828 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00004829}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004830
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004831#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004832PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004833"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004834Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004835
Barry Warsaw53699e91996-12-10 23:23:01 +00004836static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004837posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00004838{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004839#if defined(PYOS_OS2)
4840 HFILE read, write;
4841 APIRET rc;
4842
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004843 Py_BEGIN_ALLOW_THREADS
4844 rc = DosCreatePipe( &read, &write, 4096);
4845 Py_END_ALLOW_THREADS
4846 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004847 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004848
4849 return Py_BuildValue("(ii)", read, write);
4850#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004851#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00004852 int fds[2];
4853 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00004854 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004855 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00004856 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004857 if (res != 0)
4858 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004859 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004860#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00004861 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004862 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00004863 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00004864 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004865 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00004866 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00004867 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004868 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00004869 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
4870 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004871 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004872#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004873#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004874}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004875#endif /* HAVE_PIPE */
4876
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004877
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004878#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004879PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00004880"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004881Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004882
Barry Warsaw53699e91996-12-10 23:23:01 +00004883static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004884posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004885{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004886 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004887 int mode = 0666;
4888 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004889 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004890 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004891 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004892 res = mkfifo(filename, mode);
4893 Py_END_ALLOW_THREADS
4894 if (res < 0)
4895 return posix_error();
4896 Py_INCREF(Py_None);
4897 return Py_None;
4898}
4899#endif
4900
4901
Neal Norwitz11690112002-07-30 01:08:28 +00004902#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004903PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00004904"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004905Create a filesystem node (file, device special file or named pipe)\n\
4906named filename. mode specifies both the permissions to use and the\n\
4907type of node to be created, being combined (bitwise OR) with one of\n\
4908S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00004909device defines the newly created device special file (probably using\n\
4910os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004911
4912
4913static PyObject *
4914posix_mknod(PyObject *self, PyObject *args)
4915{
4916 char *filename;
4917 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00004918 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004919 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00004920 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004921 return NULL;
4922 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00004923 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00004924 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004925 if (res < 0)
4926 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004927 Py_INCREF(Py_None);
4928 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004929}
4930#endif
4931
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00004932#ifdef HAVE_DEVICE_MACROS
4933PyDoc_STRVAR(posix_major__doc__,
4934"major(device) -> major number\n\
4935Extracts a device major number from a raw device number.");
4936
4937static PyObject *
4938posix_major(PyObject *self, PyObject *args)
4939{
4940 int device;
4941 if (!PyArg_ParseTuple(args, "i:major", &device))
4942 return NULL;
4943 return PyInt_FromLong((long)major(device));
4944}
4945
4946PyDoc_STRVAR(posix_minor__doc__,
4947"minor(device) -> minor number\n\
4948Extracts a device minor number from a raw device number.");
4949
4950static PyObject *
4951posix_minor(PyObject *self, PyObject *args)
4952{
4953 int device;
4954 if (!PyArg_ParseTuple(args, "i:minor", &device))
4955 return NULL;
4956 return PyInt_FromLong((long)minor(device));
4957}
4958
4959PyDoc_STRVAR(posix_makedev__doc__,
4960"makedev(major, minor) -> device number\n\
4961Composes a raw device number from the major and minor device numbers.");
4962
4963static PyObject *
4964posix_makedev(PyObject *self, PyObject *args)
4965{
4966 int major, minor;
4967 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
4968 return NULL;
4969 return PyInt_FromLong((long)makedev(major, minor));
4970}
4971#endif /* device macros */
4972
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004973
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004974#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004975PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004976"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004977Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004978
Barry Warsaw53699e91996-12-10 23:23:01 +00004979static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004980posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004981{
4982 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004983 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004984 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004985 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004986
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004987 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004988 return NULL;
4989
4990#if !defined(HAVE_LARGEFILE_SUPPORT)
4991 length = PyInt_AsLong(lenobj);
4992#else
4993 length = PyLong_Check(lenobj) ?
4994 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
4995#endif
4996 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004997 return NULL;
4998
Barry Warsaw53699e91996-12-10 23:23:01 +00004999 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005000 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005001 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005002 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005003 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005004 return NULL;
5005 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005006 Py_INCREF(Py_None);
5007 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005008}
5009#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005010
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005011#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005012PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005013"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005014Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005015
Fred Drake762e2061999-08-26 17:23:54 +00005016/* Save putenv() parameters as values here, so we can collect them when they
5017 * get re-set with another call for the same key. */
5018static PyObject *posix_putenv_garbage;
5019
Tim Peters5aa91602002-01-30 05:46:57 +00005020static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005021posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005022{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005023#ifdef MS_WINDOWS
5024 wchar_t *s1, *s2;
5025 wchar_t *newenv;
5026#else
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005027 char *s1, *s2;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005028 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005029#endif
Fred Drake762e2061999-08-26 17:23:54 +00005030 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005031 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005032
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005033 if (!PyArg_ParseTuple(args,
5034#ifdef MS_WINDOWS
5035 "uu:putenv",
5036#else
5037 "ss:putenv",
5038#endif
5039 &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005040 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005041
5042#if defined(PYOS_OS2)
5043 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5044 APIRET rc;
5045
Guido van Rossumd48f2521997-12-05 22:19:34 +00005046 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5047 if (rc != NO_ERROR)
5048 return os2_error(rc);
5049
5050 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5051 APIRET rc;
5052
Guido van Rossumd48f2521997-12-05 22:19:34 +00005053 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5054 if (rc != NO_ERROR)
5055 return os2_error(rc);
5056 } else {
5057#endif
Fred Drake762e2061999-08-26 17:23:54 +00005058 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005059 /* len includes space for a trailing \0; the size arg to
5060 PyString_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005061#ifdef MS_WINDOWS
5062 len = wcslen(s1) + wcslen(s2) + 2;
5063 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
5064#else
5065 len = strlen(s1) + strlen(s2) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00005066 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005067#endif
Fred Drake762e2061999-08-26 17:23:54 +00005068 if (newstr == NULL)
5069 return PyErr_NoMemory();
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005070#ifdef MS_WINDOWS
5071 newenv = PyUnicode_AsUnicode(newstr);
5072 _snwprintf(newenv, len, L"%s=%s", s1, s2);
5073 if (_wputenv(newenv)) {
5074 Py_DECREF(newstr);
5075 posix_error();
5076 return NULL;
5077 }
5078#else
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005079 newenv = PyString_AS_STRING(newstr);
5080 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
5081 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005082 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005083 posix_error();
5084 return NULL;
5085 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005086#endif
Fred Drake762e2061999-08-26 17:23:54 +00005087 /* Install the first arg and newstr in posix_putenv_garbage;
5088 * this will cause previous value to be collected. This has to
5089 * happen after the real putenv() call because the old value
5090 * was still accessible until then. */
5091 if (PyDict_SetItem(posix_putenv_garbage,
5092 PyTuple_GET_ITEM(args, 0), newstr)) {
5093 /* really not much we can do; just leak */
5094 PyErr_Clear();
5095 }
5096 else {
5097 Py_DECREF(newstr);
5098 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005099
5100#if defined(PYOS_OS2)
5101 }
5102#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005103 Py_INCREF(Py_None);
5104 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005105}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005106#endif /* putenv */
5107
Guido van Rossumc524d952001-10-19 01:31:59 +00005108#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005109PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005110"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005111Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005112
5113static PyObject *
5114posix_unsetenv(PyObject *self, PyObject *args)
5115{
5116 char *s1;
5117
5118 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5119 return NULL;
5120
5121 unsetenv(s1);
5122
5123 /* Remove the key from posix_putenv_garbage;
5124 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005125 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005126 * old value was still accessible until then.
5127 */
5128 if (PyDict_DelItem(posix_putenv_garbage,
5129 PyTuple_GET_ITEM(args, 0))) {
5130 /* really not much we can do; just leak */
5131 PyErr_Clear();
5132 }
5133
5134 Py_INCREF(Py_None);
5135 return Py_None;
5136}
5137#endif /* unsetenv */
5138
Guido van Rossumb6a47161997-09-15 22:54:34 +00005139#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005140PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005141"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005142Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005143
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005144static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005145posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005146{
5147 int code;
5148 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005149 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005150 return NULL;
5151 message = strerror(code);
5152 if (message == NULL) {
5153 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005154 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005155 return NULL;
5156 }
Neal Norwitz93c56822007-08-26 07:10:06 +00005157 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00005158}
5159#endif /* strerror */
5160
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005161
Guido van Rossumc9641791998-08-04 15:26:23 +00005162#ifdef HAVE_SYS_WAIT_H
5163
Fred Drake106c1a02002-04-23 15:58:02 +00005164#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005165PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005166"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005167Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005168
5169static PyObject *
5170posix_WCOREDUMP(PyObject *self, PyObject *args)
5171{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005172 WAIT_TYPE status;
5173 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005174
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005175 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00005176 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005177
5178 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005179}
5180#endif /* WCOREDUMP */
5181
5182#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005183PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005184"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005185Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005186job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005187
5188static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005189posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005190{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005191 WAIT_TYPE status;
5192 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005193
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005194 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00005195 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005196
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005197 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005198}
5199#endif /* WIFCONTINUED */
5200
Guido van Rossumc9641791998-08-04 15:26:23 +00005201#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005202PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005203"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005204Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005205
5206static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005207posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005208{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005209 WAIT_TYPE status;
5210 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005211
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005212 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005213 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005214
Fred Drake106c1a02002-04-23 15:58:02 +00005215 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005216}
5217#endif /* WIFSTOPPED */
5218
5219#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005220PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005221"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005222Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005223
5224static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005225posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005226{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005227 WAIT_TYPE status;
5228 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005229
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005230 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005231 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005232
Fred Drake106c1a02002-04-23 15:58:02 +00005233 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005234}
5235#endif /* WIFSIGNALED */
5236
5237#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005238PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005239"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005240Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005241system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005242
5243static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005244posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005245{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005246 WAIT_TYPE status;
5247 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005248
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005249 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005250 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005251
Fred Drake106c1a02002-04-23 15:58:02 +00005252 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005253}
5254#endif /* WIFEXITED */
5255
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005256#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005257PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005258"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005259Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005260
5261static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005262posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005263{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005264 WAIT_TYPE status;
5265 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005266
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005267 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005268 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005269
Guido van Rossumc9641791998-08-04 15:26:23 +00005270 return Py_BuildValue("i", WEXITSTATUS(status));
5271}
5272#endif /* WEXITSTATUS */
5273
5274#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005275PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005276"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005277Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005278value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005279
5280static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005281posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005282{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005283 WAIT_TYPE status;
5284 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005285
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005286 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005287 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005288
Guido van Rossumc9641791998-08-04 15:26:23 +00005289 return Py_BuildValue("i", WTERMSIG(status));
5290}
5291#endif /* WTERMSIG */
5292
5293#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005294PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005295"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005296Return the signal that stopped the process that provided\n\
5297the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005298
5299static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005300posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005301{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005302 WAIT_TYPE status;
5303 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005304
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005305 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005306 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005307
Guido van Rossumc9641791998-08-04 15:26:23 +00005308 return Py_BuildValue("i", WSTOPSIG(status));
5309}
5310#endif /* WSTOPSIG */
5311
5312#endif /* HAVE_SYS_WAIT_H */
5313
5314
Thomas Wouters477c8d52006-05-27 19:21:47 +00005315#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005316#ifdef _SCO_DS
5317/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5318 needed definitions in sys/statvfs.h */
5319#define _SVID3
5320#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005321#include <sys/statvfs.h>
5322
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005323static PyObject*
5324_pystatvfs_fromstructstatvfs(struct statvfs st) {
5325 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5326 if (v == NULL)
5327 return NULL;
5328
5329#if !defined(HAVE_LARGEFILE_SUPPORT)
5330 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5331 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5332 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5333 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5334 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5335 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5336 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5337 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5338 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5339 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5340#else
5341 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5342 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005343 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005344 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005345 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005346 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005347 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005348 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005349 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005350 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005351 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005352 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005353 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005354 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005355 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5356 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5357#endif
5358
5359 return v;
5360}
5361
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005362PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005363"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005364Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005365
5366static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005367posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005368{
5369 int fd, res;
5370 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005371
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005372 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005373 return NULL;
5374 Py_BEGIN_ALLOW_THREADS
5375 res = fstatvfs(fd, &st);
5376 Py_END_ALLOW_THREADS
5377 if (res != 0)
5378 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005379
5380 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005381}
Thomas Wouters477c8d52006-05-27 19:21:47 +00005382#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005383
5384
Thomas Wouters477c8d52006-05-27 19:21:47 +00005385#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005386#include <sys/statvfs.h>
5387
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005388PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005389"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005390Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005391
5392static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005393posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005394{
5395 char *path;
5396 int res;
5397 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005398 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005399 return NULL;
5400 Py_BEGIN_ALLOW_THREADS
5401 res = statvfs(path, &st);
5402 Py_END_ALLOW_THREADS
5403 if (res != 0)
5404 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005405
5406 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005407}
5408#endif /* HAVE_STATVFS */
5409
Fred Drakec9680921999-12-13 16:37:25 +00005410/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5411 * It maps strings representing configuration variable names to
5412 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005413 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005414 * rarely-used constants. There are three separate tables that use
5415 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005416 *
5417 * This code is always included, even if none of the interfaces that
5418 * need it are included. The #if hackery needed to avoid it would be
5419 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005420 */
5421struct constdef {
5422 char *name;
5423 long value;
5424};
5425
Fred Drake12c6e2d1999-12-14 21:25:03 +00005426static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005427conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005428 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005429{
5430 if (PyInt_Check(arg)) {
5431 *valuep = PyInt_AS_LONG(arg);
5432 return 1;
5433 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00005434 else {
Fred Drake12c6e2d1999-12-14 21:25:03 +00005435 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005436 size_t lo = 0;
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005437 size_t mid;
Fred Drake699f3522000-06-29 21:12:41 +00005438 size_t hi = tablesize;
5439 int cmp;
Guido van Rossumbce56a62007-05-10 18:04:33 +00005440 const char *confname;
5441 Py_ssize_t namelen;
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005442 if (!PyUnicode_Check(arg)) {
Guido van Rossumbce56a62007-05-10 18:04:33 +00005443 PyErr_SetString(PyExc_TypeError,
5444 "configuration names must be strings or integers");
5445 return 0;
5446 }
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005447 confname = PyUnicode_AsString(arg);
5448 if (confname == NULL)
5449 return 0;
5450 namelen = strlen(confname);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005451 while (lo < hi) {
5452 mid = (lo + hi) / 2;
5453 cmp = strcmp(confname, table[mid].name);
5454 if (cmp < 0)
5455 hi = mid;
5456 else if (cmp > 0)
5457 lo = mid + 1;
5458 else {
5459 *valuep = table[mid].value;
5460 return 1;
5461 }
5462 }
5463 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
Guido van Rossumbce56a62007-05-10 18:04:33 +00005464 return 0;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005465 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00005466}
5467
5468
5469#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5470static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005471#ifdef _PC_ABI_AIO_XFER_MAX
5472 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5473#endif
5474#ifdef _PC_ABI_ASYNC_IO
5475 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5476#endif
Fred Drakec9680921999-12-13 16:37:25 +00005477#ifdef _PC_ASYNC_IO
5478 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5479#endif
5480#ifdef _PC_CHOWN_RESTRICTED
5481 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5482#endif
5483#ifdef _PC_FILESIZEBITS
5484 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5485#endif
5486#ifdef _PC_LAST
5487 {"PC_LAST", _PC_LAST},
5488#endif
5489#ifdef _PC_LINK_MAX
5490 {"PC_LINK_MAX", _PC_LINK_MAX},
5491#endif
5492#ifdef _PC_MAX_CANON
5493 {"PC_MAX_CANON", _PC_MAX_CANON},
5494#endif
5495#ifdef _PC_MAX_INPUT
5496 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5497#endif
5498#ifdef _PC_NAME_MAX
5499 {"PC_NAME_MAX", _PC_NAME_MAX},
5500#endif
5501#ifdef _PC_NO_TRUNC
5502 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5503#endif
5504#ifdef _PC_PATH_MAX
5505 {"PC_PATH_MAX", _PC_PATH_MAX},
5506#endif
5507#ifdef _PC_PIPE_BUF
5508 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5509#endif
5510#ifdef _PC_PRIO_IO
5511 {"PC_PRIO_IO", _PC_PRIO_IO},
5512#endif
5513#ifdef _PC_SOCK_MAXBUF
5514 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5515#endif
5516#ifdef _PC_SYNC_IO
5517 {"PC_SYNC_IO", _PC_SYNC_IO},
5518#endif
5519#ifdef _PC_VDISABLE
5520 {"PC_VDISABLE", _PC_VDISABLE},
5521#endif
5522};
5523
Fred Drakec9680921999-12-13 16:37:25 +00005524static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005525conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005526{
5527 return conv_confname(arg, valuep, posix_constants_pathconf,
5528 sizeof(posix_constants_pathconf)
5529 / sizeof(struct constdef));
5530}
5531#endif
5532
5533#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005534PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005535"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005536Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005537If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005538
5539static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005540posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005541{
5542 PyObject *result = NULL;
5543 int name, fd;
5544
Fred Drake12c6e2d1999-12-14 21:25:03 +00005545 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5546 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005547 long limit;
5548
5549 errno = 0;
5550 limit = fpathconf(fd, name);
5551 if (limit == -1 && errno != 0)
5552 posix_error();
5553 else
5554 result = PyInt_FromLong(limit);
5555 }
5556 return result;
5557}
5558#endif
5559
5560
5561#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005562PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005563"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005564Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005565If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005566
5567static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005568posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005569{
5570 PyObject *result = NULL;
5571 int name;
5572 char *path;
5573
5574 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5575 conv_path_confname, &name)) {
5576 long limit;
5577
5578 errno = 0;
5579 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005580 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005581 if (errno == EINVAL)
5582 /* could be a path or name problem */
5583 posix_error();
5584 else
5585 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005586 }
Fred Drakec9680921999-12-13 16:37:25 +00005587 else
5588 result = PyInt_FromLong(limit);
5589 }
5590 return result;
5591}
5592#endif
5593
5594#ifdef HAVE_CONFSTR
5595static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005596#ifdef _CS_ARCHITECTURE
5597 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5598#endif
5599#ifdef _CS_HOSTNAME
5600 {"CS_HOSTNAME", _CS_HOSTNAME},
5601#endif
5602#ifdef _CS_HW_PROVIDER
5603 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5604#endif
5605#ifdef _CS_HW_SERIAL
5606 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5607#endif
5608#ifdef _CS_INITTAB_NAME
5609 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5610#endif
Fred Drakec9680921999-12-13 16:37:25 +00005611#ifdef _CS_LFS64_CFLAGS
5612 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5613#endif
5614#ifdef _CS_LFS64_LDFLAGS
5615 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5616#endif
5617#ifdef _CS_LFS64_LIBS
5618 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5619#endif
5620#ifdef _CS_LFS64_LINTFLAGS
5621 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5622#endif
5623#ifdef _CS_LFS_CFLAGS
5624 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5625#endif
5626#ifdef _CS_LFS_LDFLAGS
5627 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5628#endif
5629#ifdef _CS_LFS_LIBS
5630 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5631#endif
5632#ifdef _CS_LFS_LINTFLAGS
5633 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5634#endif
Fred Draked86ed291999-12-15 15:34:33 +00005635#ifdef _CS_MACHINE
5636 {"CS_MACHINE", _CS_MACHINE},
5637#endif
Fred Drakec9680921999-12-13 16:37:25 +00005638#ifdef _CS_PATH
5639 {"CS_PATH", _CS_PATH},
5640#endif
Fred Draked86ed291999-12-15 15:34:33 +00005641#ifdef _CS_RELEASE
5642 {"CS_RELEASE", _CS_RELEASE},
5643#endif
5644#ifdef _CS_SRPC_DOMAIN
5645 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5646#endif
5647#ifdef _CS_SYSNAME
5648 {"CS_SYSNAME", _CS_SYSNAME},
5649#endif
5650#ifdef _CS_VERSION
5651 {"CS_VERSION", _CS_VERSION},
5652#endif
Fred Drakec9680921999-12-13 16:37:25 +00005653#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5654 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5655#endif
5656#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5657 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5658#endif
5659#ifdef _CS_XBS5_ILP32_OFF32_LIBS
5660 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5661#endif
5662#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5663 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5664#endif
5665#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5666 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5667#endif
5668#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5669 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5670#endif
5671#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
5672 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
5673#endif
5674#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
5675 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
5676#endif
5677#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
5678 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
5679#endif
5680#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
5681 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
5682#endif
5683#ifdef _CS_XBS5_LP64_OFF64_LIBS
5684 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
5685#endif
5686#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
5687 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
5688#endif
5689#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
5690 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
5691#endif
5692#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
5693 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
5694#endif
5695#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
5696 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
5697#endif
5698#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
5699 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
5700#endif
Fred Draked86ed291999-12-15 15:34:33 +00005701#ifdef _MIPS_CS_AVAIL_PROCESSORS
5702 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
5703#endif
5704#ifdef _MIPS_CS_BASE
5705 {"MIPS_CS_BASE", _MIPS_CS_BASE},
5706#endif
5707#ifdef _MIPS_CS_HOSTID
5708 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
5709#endif
5710#ifdef _MIPS_CS_HW_NAME
5711 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
5712#endif
5713#ifdef _MIPS_CS_NUM_PROCESSORS
5714 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
5715#endif
5716#ifdef _MIPS_CS_OSREL_MAJ
5717 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
5718#endif
5719#ifdef _MIPS_CS_OSREL_MIN
5720 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
5721#endif
5722#ifdef _MIPS_CS_OSREL_PATCH
5723 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
5724#endif
5725#ifdef _MIPS_CS_OS_NAME
5726 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
5727#endif
5728#ifdef _MIPS_CS_OS_PROVIDER
5729 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
5730#endif
5731#ifdef _MIPS_CS_PROCESSORS
5732 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
5733#endif
5734#ifdef _MIPS_CS_SERIAL
5735 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
5736#endif
5737#ifdef _MIPS_CS_VENDOR
5738 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
5739#endif
Fred Drakec9680921999-12-13 16:37:25 +00005740};
5741
5742static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005743conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005744{
5745 return conv_confname(arg, valuep, posix_constants_confstr,
5746 sizeof(posix_constants_confstr)
5747 / sizeof(struct constdef));
5748}
5749
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005750PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005751"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005752Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00005753
5754static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005755posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005756{
5757 PyObject *result = NULL;
5758 int name;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005759 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00005760
5761 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005762 int len;
Fred Drakec9680921999-12-13 16:37:25 +00005763
Fred Drakec9680921999-12-13 16:37:25 +00005764 errno = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005765 len = confstr(name, buffer, sizeof(buffer));
5766 if (len == 0) {
5767 if (errno) {
5768 posix_error();
5769 }
5770 else {
5771 result = Py_None;
5772 Py_INCREF(Py_None);
5773 }
Fred Drakec9680921999-12-13 16:37:25 +00005774 }
5775 else {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005776 if ((unsigned int)len >= sizeof(buffer)) {
Neal Norwitz93c56822007-08-26 07:10:06 +00005777 result = PyUnicode_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00005778 if (result != NULL)
Neal Norwitz93c56822007-08-26 07:10:06 +00005779 confstr(name, PyUnicode_AsString(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00005780 }
5781 else
Neal Norwitz93c56822007-08-26 07:10:06 +00005782 result = PyUnicode_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00005783 }
5784 }
5785 return result;
5786}
5787#endif
5788
5789
5790#ifdef HAVE_SYSCONF
5791static struct constdef posix_constants_sysconf[] = {
5792#ifdef _SC_2_CHAR_TERM
5793 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
5794#endif
5795#ifdef _SC_2_C_BIND
5796 {"SC_2_C_BIND", _SC_2_C_BIND},
5797#endif
5798#ifdef _SC_2_C_DEV
5799 {"SC_2_C_DEV", _SC_2_C_DEV},
5800#endif
5801#ifdef _SC_2_C_VERSION
5802 {"SC_2_C_VERSION", _SC_2_C_VERSION},
5803#endif
5804#ifdef _SC_2_FORT_DEV
5805 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
5806#endif
5807#ifdef _SC_2_FORT_RUN
5808 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
5809#endif
5810#ifdef _SC_2_LOCALEDEF
5811 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
5812#endif
5813#ifdef _SC_2_SW_DEV
5814 {"SC_2_SW_DEV", _SC_2_SW_DEV},
5815#endif
5816#ifdef _SC_2_UPE
5817 {"SC_2_UPE", _SC_2_UPE},
5818#endif
5819#ifdef _SC_2_VERSION
5820 {"SC_2_VERSION", _SC_2_VERSION},
5821#endif
Fred Draked86ed291999-12-15 15:34:33 +00005822#ifdef _SC_ABI_ASYNCHRONOUS_IO
5823 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
5824#endif
5825#ifdef _SC_ACL
5826 {"SC_ACL", _SC_ACL},
5827#endif
Fred Drakec9680921999-12-13 16:37:25 +00005828#ifdef _SC_AIO_LISTIO_MAX
5829 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
5830#endif
Fred Drakec9680921999-12-13 16:37:25 +00005831#ifdef _SC_AIO_MAX
5832 {"SC_AIO_MAX", _SC_AIO_MAX},
5833#endif
5834#ifdef _SC_AIO_PRIO_DELTA_MAX
5835 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
5836#endif
5837#ifdef _SC_ARG_MAX
5838 {"SC_ARG_MAX", _SC_ARG_MAX},
5839#endif
5840#ifdef _SC_ASYNCHRONOUS_IO
5841 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
5842#endif
5843#ifdef _SC_ATEXIT_MAX
5844 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
5845#endif
Fred Draked86ed291999-12-15 15:34:33 +00005846#ifdef _SC_AUDIT
5847 {"SC_AUDIT", _SC_AUDIT},
5848#endif
Fred Drakec9680921999-12-13 16:37:25 +00005849#ifdef _SC_AVPHYS_PAGES
5850 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
5851#endif
5852#ifdef _SC_BC_BASE_MAX
5853 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
5854#endif
5855#ifdef _SC_BC_DIM_MAX
5856 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
5857#endif
5858#ifdef _SC_BC_SCALE_MAX
5859 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
5860#endif
5861#ifdef _SC_BC_STRING_MAX
5862 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
5863#endif
Fred Draked86ed291999-12-15 15:34:33 +00005864#ifdef _SC_CAP
5865 {"SC_CAP", _SC_CAP},
5866#endif
Fred Drakec9680921999-12-13 16:37:25 +00005867#ifdef _SC_CHARCLASS_NAME_MAX
5868 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
5869#endif
5870#ifdef _SC_CHAR_BIT
5871 {"SC_CHAR_BIT", _SC_CHAR_BIT},
5872#endif
5873#ifdef _SC_CHAR_MAX
5874 {"SC_CHAR_MAX", _SC_CHAR_MAX},
5875#endif
5876#ifdef _SC_CHAR_MIN
5877 {"SC_CHAR_MIN", _SC_CHAR_MIN},
5878#endif
5879#ifdef _SC_CHILD_MAX
5880 {"SC_CHILD_MAX", _SC_CHILD_MAX},
5881#endif
5882#ifdef _SC_CLK_TCK
5883 {"SC_CLK_TCK", _SC_CLK_TCK},
5884#endif
5885#ifdef _SC_COHER_BLKSZ
5886 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
5887#endif
5888#ifdef _SC_COLL_WEIGHTS_MAX
5889 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
5890#endif
5891#ifdef _SC_DCACHE_ASSOC
5892 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
5893#endif
5894#ifdef _SC_DCACHE_BLKSZ
5895 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
5896#endif
5897#ifdef _SC_DCACHE_LINESZ
5898 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
5899#endif
5900#ifdef _SC_DCACHE_SZ
5901 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
5902#endif
5903#ifdef _SC_DCACHE_TBLKSZ
5904 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
5905#endif
5906#ifdef _SC_DELAYTIMER_MAX
5907 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
5908#endif
5909#ifdef _SC_EQUIV_CLASS_MAX
5910 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
5911#endif
5912#ifdef _SC_EXPR_NEST_MAX
5913 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
5914#endif
5915#ifdef _SC_FSYNC
5916 {"SC_FSYNC", _SC_FSYNC},
5917#endif
5918#ifdef _SC_GETGR_R_SIZE_MAX
5919 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
5920#endif
5921#ifdef _SC_GETPW_R_SIZE_MAX
5922 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
5923#endif
5924#ifdef _SC_ICACHE_ASSOC
5925 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
5926#endif
5927#ifdef _SC_ICACHE_BLKSZ
5928 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
5929#endif
5930#ifdef _SC_ICACHE_LINESZ
5931 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
5932#endif
5933#ifdef _SC_ICACHE_SZ
5934 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
5935#endif
Fred Draked86ed291999-12-15 15:34:33 +00005936#ifdef _SC_INF
5937 {"SC_INF", _SC_INF},
5938#endif
Fred Drakec9680921999-12-13 16:37:25 +00005939#ifdef _SC_INT_MAX
5940 {"SC_INT_MAX", _SC_INT_MAX},
5941#endif
5942#ifdef _SC_INT_MIN
5943 {"SC_INT_MIN", _SC_INT_MIN},
5944#endif
5945#ifdef _SC_IOV_MAX
5946 {"SC_IOV_MAX", _SC_IOV_MAX},
5947#endif
Fred Draked86ed291999-12-15 15:34:33 +00005948#ifdef _SC_IP_SECOPTS
5949 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
5950#endif
Fred Drakec9680921999-12-13 16:37:25 +00005951#ifdef _SC_JOB_CONTROL
5952 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
5953#endif
Fred Draked86ed291999-12-15 15:34:33 +00005954#ifdef _SC_KERN_POINTERS
5955 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
5956#endif
5957#ifdef _SC_KERN_SIM
5958 {"SC_KERN_SIM", _SC_KERN_SIM},
5959#endif
Fred Drakec9680921999-12-13 16:37:25 +00005960#ifdef _SC_LINE_MAX
5961 {"SC_LINE_MAX", _SC_LINE_MAX},
5962#endif
5963#ifdef _SC_LOGIN_NAME_MAX
5964 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
5965#endif
5966#ifdef _SC_LOGNAME_MAX
5967 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
5968#endif
5969#ifdef _SC_LONG_BIT
5970 {"SC_LONG_BIT", _SC_LONG_BIT},
5971#endif
Fred Draked86ed291999-12-15 15:34:33 +00005972#ifdef _SC_MAC
5973 {"SC_MAC", _SC_MAC},
5974#endif
Fred Drakec9680921999-12-13 16:37:25 +00005975#ifdef _SC_MAPPED_FILES
5976 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
5977#endif
5978#ifdef _SC_MAXPID
5979 {"SC_MAXPID", _SC_MAXPID},
5980#endif
5981#ifdef _SC_MB_LEN_MAX
5982 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
5983#endif
5984#ifdef _SC_MEMLOCK
5985 {"SC_MEMLOCK", _SC_MEMLOCK},
5986#endif
5987#ifdef _SC_MEMLOCK_RANGE
5988 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
5989#endif
5990#ifdef _SC_MEMORY_PROTECTION
5991 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
5992#endif
5993#ifdef _SC_MESSAGE_PASSING
5994 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
5995#endif
Fred Draked86ed291999-12-15 15:34:33 +00005996#ifdef _SC_MMAP_FIXED_ALIGNMENT
5997 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
5998#endif
Fred Drakec9680921999-12-13 16:37:25 +00005999#ifdef _SC_MQ_OPEN_MAX
6000 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6001#endif
6002#ifdef _SC_MQ_PRIO_MAX
6003 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6004#endif
Fred Draked86ed291999-12-15 15:34:33 +00006005#ifdef _SC_NACLS_MAX
6006 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6007#endif
Fred Drakec9680921999-12-13 16:37:25 +00006008#ifdef _SC_NGROUPS_MAX
6009 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6010#endif
6011#ifdef _SC_NL_ARGMAX
6012 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6013#endif
6014#ifdef _SC_NL_LANGMAX
6015 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6016#endif
6017#ifdef _SC_NL_MSGMAX
6018 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6019#endif
6020#ifdef _SC_NL_NMAX
6021 {"SC_NL_NMAX", _SC_NL_NMAX},
6022#endif
6023#ifdef _SC_NL_SETMAX
6024 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6025#endif
6026#ifdef _SC_NL_TEXTMAX
6027 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6028#endif
6029#ifdef _SC_NPROCESSORS_CONF
6030 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6031#endif
6032#ifdef _SC_NPROCESSORS_ONLN
6033 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6034#endif
Fred Draked86ed291999-12-15 15:34:33 +00006035#ifdef _SC_NPROC_CONF
6036 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6037#endif
6038#ifdef _SC_NPROC_ONLN
6039 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6040#endif
Fred Drakec9680921999-12-13 16:37:25 +00006041#ifdef _SC_NZERO
6042 {"SC_NZERO", _SC_NZERO},
6043#endif
6044#ifdef _SC_OPEN_MAX
6045 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6046#endif
6047#ifdef _SC_PAGESIZE
6048 {"SC_PAGESIZE", _SC_PAGESIZE},
6049#endif
6050#ifdef _SC_PAGE_SIZE
6051 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6052#endif
6053#ifdef _SC_PASS_MAX
6054 {"SC_PASS_MAX", _SC_PASS_MAX},
6055#endif
6056#ifdef _SC_PHYS_PAGES
6057 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6058#endif
6059#ifdef _SC_PII
6060 {"SC_PII", _SC_PII},
6061#endif
6062#ifdef _SC_PII_INTERNET
6063 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6064#endif
6065#ifdef _SC_PII_INTERNET_DGRAM
6066 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6067#endif
6068#ifdef _SC_PII_INTERNET_STREAM
6069 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6070#endif
6071#ifdef _SC_PII_OSI
6072 {"SC_PII_OSI", _SC_PII_OSI},
6073#endif
6074#ifdef _SC_PII_OSI_CLTS
6075 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6076#endif
6077#ifdef _SC_PII_OSI_COTS
6078 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6079#endif
6080#ifdef _SC_PII_OSI_M
6081 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6082#endif
6083#ifdef _SC_PII_SOCKET
6084 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6085#endif
6086#ifdef _SC_PII_XTI
6087 {"SC_PII_XTI", _SC_PII_XTI},
6088#endif
6089#ifdef _SC_POLL
6090 {"SC_POLL", _SC_POLL},
6091#endif
6092#ifdef _SC_PRIORITIZED_IO
6093 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6094#endif
6095#ifdef _SC_PRIORITY_SCHEDULING
6096 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6097#endif
6098#ifdef _SC_REALTIME_SIGNALS
6099 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6100#endif
6101#ifdef _SC_RE_DUP_MAX
6102 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6103#endif
6104#ifdef _SC_RTSIG_MAX
6105 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6106#endif
6107#ifdef _SC_SAVED_IDS
6108 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6109#endif
6110#ifdef _SC_SCHAR_MAX
6111 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6112#endif
6113#ifdef _SC_SCHAR_MIN
6114 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6115#endif
6116#ifdef _SC_SELECT
6117 {"SC_SELECT", _SC_SELECT},
6118#endif
6119#ifdef _SC_SEMAPHORES
6120 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6121#endif
6122#ifdef _SC_SEM_NSEMS_MAX
6123 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6124#endif
6125#ifdef _SC_SEM_VALUE_MAX
6126 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6127#endif
6128#ifdef _SC_SHARED_MEMORY_OBJECTS
6129 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6130#endif
6131#ifdef _SC_SHRT_MAX
6132 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6133#endif
6134#ifdef _SC_SHRT_MIN
6135 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6136#endif
6137#ifdef _SC_SIGQUEUE_MAX
6138 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6139#endif
6140#ifdef _SC_SIGRT_MAX
6141 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6142#endif
6143#ifdef _SC_SIGRT_MIN
6144 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6145#endif
Fred Draked86ed291999-12-15 15:34:33 +00006146#ifdef _SC_SOFTPOWER
6147 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6148#endif
Fred Drakec9680921999-12-13 16:37:25 +00006149#ifdef _SC_SPLIT_CACHE
6150 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6151#endif
6152#ifdef _SC_SSIZE_MAX
6153 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6154#endif
6155#ifdef _SC_STACK_PROT
6156 {"SC_STACK_PROT", _SC_STACK_PROT},
6157#endif
6158#ifdef _SC_STREAM_MAX
6159 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6160#endif
6161#ifdef _SC_SYNCHRONIZED_IO
6162 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6163#endif
6164#ifdef _SC_THREADS
6165 {"SC_THREADS", _SC_THREADS},
6166#endif
6167#ifdef _SC_THREAD_ATTR_STACKADDR
6168 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6169#endif
6170#ifdef _SC_THREAD_ATTR_STACKSIZE
6171 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6172#endif
6173#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6174 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6175#endif
6176#ifdef _SC_THREAD_KEYS_MAX
6177 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6178#endif
6179#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6180 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6181#endif
6182#ifdef _SC_THREAD_PRIO_INHERIT
6183 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6184#endif
6185#ifdef _SC_THREAD_PRIO_PROTECT
6186 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6187#endif
6188#ifdef _SC_THREAD_PROCESS_SHARED
6189 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6190#endif
6191#ifdef _SC_THREAD_SAFE_FUNCTIONS
6192 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6193#endif
6194#ifdef _SC_THREAD_STACK_MIN
6195 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6196#endif
6197#ifdef _SC_THREAD_THREADS_MAX
6198 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6199#endif
6200#ifdef _SC_TIMERS
6201 {"SC_TIMERS", _SC_TIMERS},
6202#endif
6203#ifdef _SC_TIMER_MAX
6204 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6205#endif
6206#ifdef _SC_TTY_NAME_MAX
6207 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6208#endif
6209#ifdef _SC_TZNAME_MAX
6210 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6211#endif
6212#ifdef _SC_T_IOV_MAX
6213 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6214#endif
6215#ifdef _SC_UCHAR_MAX
6216 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6217#endif
6218#ifdef _SC_UINT_MAX
6219 {"SC_UINT_MAX", _SC_UINT_MAX},
6220#endif
6221#ifdef _SC_UIO_MAXIOV
6222 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6223#endif
6224#ifdef _SC_ULONG_MAX
6225 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6226#endif
6227#ifdef _SC_USHRT_MAX
6228 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6229#endif
6230#ifdef _SC_VERSION
6231 {"SC_VERSION", _SC_VERSION},
6232#endif
6233#ifdef _SC_WORD_BIT
6234 {"SC_WORD_BIT", _SC_WORD_BIT},
6235#endif
6236#ifdef _SC_XBS5_ILP32_OFF32
6237 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6238#endif
6239#ifdef _SC_XBS5_ILP32_OFFBIG
6240 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6241#endif
6242#ifdef _SC_XBS5_LP64_OFF64
6243 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6244#endif
6245#ifdef _SC_XBS5_LPBIG_OFFBIG
6246 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6247#endif
6248#ifdef _SC_XOPEN_CRYPT
6249 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6250#endif
6251#ifdef _SC_XOPEN_ENH_I18N
6252 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6253#endif
6254#ifdef _SC_XOPEN_LEGACY
6255 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6256#endif
6257#ifdef _SC_XOPEN_REALTIME
6258 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6259#endif
6260#ifdef _SC_XOPEN_REALTIME_THREADS
6261 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6262#endif
6263#ifdef _SC_XOPEN_SHM
6264 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6265#endif
6266#ifdef _SC_XOPEN_UNIX
6267 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6268#endif
6269#ifdef _SC_XOPEN_VERSION
6270 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6271#endif
6272#ifdef _SC_XOPEN_XCU_VERSION
6273 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6274#endif
6275#ifdef _SC_XOPEN_XPG2
6276 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6277#endif
6278#ifdef _SC_XOPEN_XPG3
6279 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6280#endif
6281#ifdef _SC_XOPEN_XPG4
6282 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6283#endif
6284};
6285
6286static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006287conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006288{
6289 return conv_confname(arg, valuep, posix_constants_sysconf,
6290 sizeof(posix_constants_sysconf)
6291 / sizeof(struct constdef));
6292}
6293
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006294PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006295"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006296Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006297
6298static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006299posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006300{
6301 PyObject *result = NULL;
6302 int name;
6303
6304 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6305 int value;
6306
6307 errno = 0;
6308 value = sysconf(name);
6309 if (value == -1 && errno != 0)
6310 posix_error();
6311 else
6312 result = PyInt_FromLong(value);
6313 }
6314 return result;
6315}
6316#endif
6317
6318
Fred Drakebec628d1999-12-15 18:31:10 +00006319/* This code is used to ensure that the tables of configuration value names
6320 * are in sorted order as required by conv_confname(), and also to build the
6321 * the exported dictionaries that are used to publish information about the
6322 * names available on the host platform.
6323 *
6324 * Sorting the table at runtime ensures that the table is properly ordered
6325 * when used, even for platforms we're not able to test on. It also makes
6326 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006327 */
Fred Drakebec628d1999-12-15 18:31:10 +00006328
6329static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006330cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006331{
6332 const struct constdef *c1 =
6333 (const struct constdef *) v1;
6334 const struct constdef *c2 =
6335 (const struct constdef *) v2;
6336
6337 return strcmp(c1->name, c2->name);
6338}
6339
6340static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006341setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006342 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006343{
Fred Drakebec628d1999-12-15 18:31:10 +00006344 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006345 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006346
6347 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6348 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006349 if (d == NULL)
6350 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006351
Barry Warsaw3155db32000-04-13 15:20:40 +00006352 for (i=0; i < tablesize; ++i) {
6353 PyObject *o = PyInt_FromLong(table[i].value);
6354 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6355 Py_XDECREF(o);
6356 Py_DECREF(d);
6357 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006358 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006359 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006360 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006361 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006362}
6363
Fred Drakebec628d1999-12-15 18:31:10 +00006364/* Return -1 on failure, 0 on success. */
6365static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006366setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006367{
6368#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006369 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006370 sizeof(posix_constants_pathconf)
6371 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006372 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006373 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006374#endif
6375#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006376 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006377 sizeof(posix_constants_confstr)
6378 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006379 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006380 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006381#endif
6382#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006383 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006384 sizeof(posix_constants_sysconf)
6385 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006386 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006387 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006388#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006389 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006390}
Fred Draked86ed291999-12-15 15:34:33 +00006391
6392
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006393PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006394"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006395Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006396in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006397
6398static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006399posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006400{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006401 abort();
6402 /*NOTREACHED*/
6403 Py_FatalError("abort() called from Python code didn't abort!");
6404 return NULL;
6405}
Fred Drakebec628d1999-12-15 18:31:10 +00006406
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006407#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006408PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00006409"startfile(filepath [, operation]) - Start a file with its associated\n\
6410application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006411\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00006412When \"operation\" is not specified or \"open\", this acts like\n\
6413double-clicking the file in Explorer, or giving the file name as an\n\
6414argument to the DOS \"start\" command: the file is opened with whatever\n\
6415application (if any) its extension is associated.\n\
6416When another \"operation\" is given, it specifies what should be done with\n\
6417the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006418\n\
6419startfile returns as soon as the associated application is launched.\n\
6420There is no option to wait for the application to close, and no way\n\
6421to retrieve the application's exit status.\n\
6422\n\
6423The filepath is relative to the current directory. If you want to use\n\
6424an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006425the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006426
6427static PyObject *
6428win32_startfile(PyObject *self, PyObject *args)
6429{
6430 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00006431 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00006432 HINSTANCE rc;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006433#ifdef Py_WIN_WIDE_FILENAMES
6434 if (unicode_file_names()) {
6435 PyObject *unipath, *woperation = NULL;
6436 if (!PyArg_ParseTuple(args, "U|s:startfile",
6437 &unipath, &operation)) {
6438 PyErr_Clear();
6439 goto normal;
6440 }
6441
6442
6443 if (operation) {
6444 woperation = PyUnicode_DecodeASCII(operation,
6445 strlen(operation), NULL);
6446 if (!woperation) {
6447 PyErr_Clear();
6448 operation = NULL;
6449 goto normal;
6450 }
6451 }
6452
6453 Py_BEGIN_ALLOW_THREADS
6454 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
6455 PyUnicode_AS_UNICODE(unipath),
6456 NULL, NULL, SW_SHOWNORMAL);
6457 Py_END_ALLOW_THREADS
6458
6459 Py_XDECREF(woperation);
6460 if (rc <= (HINSTANCE)32) {
6461 PyObject *errval = win32_error_unicode("startfile",
6462 PyUnicode_AS_UNICODE(unipath));
6463 return errval;
6464 }
6465 Py_INCREF(Py_None);
6466 return Py_None;
6467 }
6468#endif
6469
6470normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00006471 if (!PyArg_ParseTuple(args, "et|s:startfile",
6472 Py_FileSystemDefaultEncoding, &filepath,
6473 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00006474 return NULL;
6475 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00006476 rc = ShellExecute((HWND)0, operation, filepath,
6477 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00006478 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00006479 if (rc <= (HINSTANCE)32) {
6480 PyObject *errval = win32_error("startfile", filepath);
6481 PyMem_Free(filepath);
6482 return errval;
6483 }
6484 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00006485 Py_INCREF(Py_None);
6486 return Py_None;
6487}
6488#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006489
Martin v. Löwis438b5342002-12-27 10:16:42 +00006490#ifdef HAVE_GETLOADAVG
6491PyDoc_STRVAR(posix_getloadavg__doc__,
6492"getloadavg() -> (float, float, float)\n\n\
6493Return the number of processes in the system run queue averaged over\n\
6494the last 1, 5, and 15 minutes or raises OSError if the load average\n\
6495was unobtainable");
6496
6497static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006498posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00006499{
6500 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00006501 if (getloadavg(loadavg, 3)!=3) {
6502 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
6503 return NULL;
6504 } else
6505 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
6506}
6507#endif
6508
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006509#ifdef MS_WINDOWS
6510
6511PyDoc_STRVAR(win32_urandom__doc__,
6512"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00006513Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006514
6515typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
6516 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
6517 DWORD dwFlags );
6518typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
6519 BYTE *pbBuffer );
6520
6521static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00006522/* This handle is never explicitly released. Instead, the operating
6523 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006524static HCRYPTPROV hCryptProv = 0;
6525
Tim Peters4ad82172004-08-30 17:02:04 +00006526static PyObject*
6527win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006528{
Tim Petersd3115382004-08-30 17:36:46 +00006529 int howMany;
6530 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006531
Tim Peters4ad82172004-08-30 17:02:04 +00006532 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00006533 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00006534 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00006535 if (howMany < 0)
6536 return PyErr_Format(PyExc_ValueError,
6537 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006538
Tim Peters4ad82172004-08-30 17:02:04 +00006539 if (hCryptProv == 0) {
6540 HINSTANCE hAdvAPI32 = NULL;
6541 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006542
Tim Peters4ad82172004-08-30 17:02:04 +00006543 /* Obtain handle to the DLL containing CryptoAPI
6544 This should not fail */
6545 hAdvAPI32 = GetModuleHandle("advapi32.dll");
6546 if(hAdvAPI32 == NULL)
6547 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006548
Tim Peters4ad82172004-08-30 17:02:04 +00006549 /* Obtain pointers to the CryptoAPI functions
6550 This will fail on some early versions of Win95 */
6551 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
6552 hAdvAPI32,
6553 "CryptAcquireContextA");
6554 if (pCryptAcquireContext == NULL)
6555 return PyErr_Format(PyExc_NotImplementedError,
6556 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006557
Tim Peters4ad82172004-08-30 17:02:04 +00006558 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
6559 hAdvAPI32, "CryptGenRandom");
Thomas Wouters89f507f2006-12-13 04:49:30 +00006560 if (pCryptGenRandom == NULL)
Tim Peters4ad82172004-08-30 17:02:04 +00006561 return PyErr_Format(PyExc_NotImplementedError,
6562 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006563
Tim Peters4ad82172004-08-30 17:02:04 +00006564 /* Acquire context */
6565 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
6566 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
6567 return win32_error("CryptAcquireContext", NULL);
6568 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006569
Tim Peters4ad82172004-08-30 17:02:04 +00006570 /* Allocate bytes */
Neal Norwitz93c56822007-08-26 07:10:06 +00006571 result = PyBytes_FromStringAndSize(NULL, howMany);
Tim Petersd3115382004-08-30 17:36:46 +00006572 if (result != NULL) {
6573 /* Get random data */
6574 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
Neal Norwitz93c56822007-08-26 07:10:06 +00006575 PyBytes_AS_STRING(result))) {
Tim Petersd3115382004-08-30 17:36:46 +00006576 Py_DECREF(result);
6577 return win32_error("CryptGenRandom", NULL);
6578 }
Tim Peters4ad82172004-08-30 17:02:04 +00006579 }
Tim Petersd3115382004-08-30 17:36:46 +00006580 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006581}
6582#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00006583
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00006584PyDoc_STRVAR(device_encoding__doc__,
6585"device_encoding(fd) -> str\n\n\
6586Return a string describing the encoding of the device\n\
6587if the output is a terminal; else return None.");
6588
6589static PyObject *
6590device_encoding(PyObject *self, PyObject *args)
6591{
6592 int fd;
6593 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
6594 return NULL;
6595 if (!isatty(fd)) {
6596 Py_INCREF(Py_None);
6597 return Py_None;
6598 }
6599#if defined(MS_WINDOWS) || defined(MS_WIN64)
6600 if (fd == 0) {
6601 char buf[100];
6602 sprintf(buf, "cp%d", GetConsoleCP());
6603 return PyUnicode_FromString(buf);
6604 }
6605 if (fd == 1 || fd == 2) {
6606 char buf[100];
6607 sprintf(buf, "cp%d", GetConsoleOutputCP());
6608 return PyUnicode_FromString(buf);
6609 }
6610#elif defined(CODESET)
6611 {
6612 char *codeset = nl_langinfo(CODESET);
6613 if (codeset)
6614 return PyUnicode_FromString(codeset);
6615 }
6616#endif
6617 Py_INCREF(Py_None);
6618 return Py_None;
6619}
6620
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006621#ifdef __VMS
6622/* Use openssl random routine */
6623#include <openssl/rand.h>
6624PyDoc_STRVAR(vms_urandom__doc__,
6625"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00006626Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006627
6628static PyObject*
6629vms_urandom(PyObject *self, PyObject *args)
6630{
6631 int howMany;
6632 PyObject* result;
6633
6634 /* Read arguments */
6635 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
6636 return NULL;
6637 if (howMany < 0)
6638 return PyErr_Format(PyExc_ValueError,
6639 "negative argument not allowed");
6640
6641 /* Allocate bytes */
Neal Norwitz93c56822007-08-26 07:10:06 +00006642 result = PyBytes_FromStringAndSize(NULL, howMany);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006643 if (result != NULL) {
6644 /* Get random data */
6645 if (RAND_pseudo_bytes((unsigned char*)
Neal Norwitz93c56822007-08-26 07:10:06 +00006646 PyBytes_AS_STRING(result),
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006647 howMany) < 0) {
6648 Py_DECREF(result);
6649 return PyErr_Format(PyExc_ValueError,
6650 "RAND_pseudo_bytes");
6651 }
6652 }
6653 return result;
6654}
6655#endif
6656
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006657static PyMethodDef posix_methods[] = {
6658 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6659#ifdef HAVE_TTYNAME
6660 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6661#endif
6662 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00006663#ifdef HAVE_CHFLAGS
6664 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
6665#endif /* HAVE_CHFLAGS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006666 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006667#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006668 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006669#endif /* HAVE_CHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00006670#ifdef HAVE_LCHFLAGS
6671 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
6672#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00006673#ifdef HAVE_LCHOWN
6674 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
6675#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006676#ifdef HAVE_CHROOT
6677 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6678#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006679#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00006680 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006681#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006682#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00006683 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Neal Norwitze241ce82003-02-17 18:17:05 +00006684 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006685#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006686#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006687 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006688#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006689 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6690 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6691 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006692#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006693 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006694#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006695#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006696 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006697#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006698 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6699 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6700 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00006701 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006702#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006703 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006704#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006705#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006706 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006707#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006708 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006709#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00006710 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006711#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006712 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6713 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6714 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006715#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00006716 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006717#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006718 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006719#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006720 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6721 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006722#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006723#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006724 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6725 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00006726#if defined(PYOS_OS2)
6727 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
6728 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
6729#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00006730#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006731#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00006732 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006733#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006734#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00006735 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006736#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006737#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00006738 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006739#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006740#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00006741 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00006742#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006743#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00006744 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006745#endif /* HAVE_GETEGID */
6746#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00006747 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006748#endif /* HAVE_GETEUID */
6749#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00006750 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006751#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006752#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00006753 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00006754#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00006755 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006756#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00006757 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006758#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006759#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00006760 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006761#endif /* HAVE_GETPPID */
6762#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00006763 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006764#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006765#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00006766 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00006767#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006768#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006769 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006770#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006771#ifdef HAVE_KILLPG
6772 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6773#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006774#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006775 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006776#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +00006777#ifdef MS_WINDOWS
6778 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
6779#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006780#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006781 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006782#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006783#ifdef HAVE_SETEUID
6784 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6785#endif /* HAVE_SETEUID */
6786#ifdef HAVE_SETEGID
6787 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6788#endif /* HAVE_SETEGID */
6789#ifdef HAVE_SETREUID
6790 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6791#endif /* HAVE_SETREUID */
6792#ifdef HAVE_SETREGID
6793 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6794#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006795#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006796 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006797#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006798#ifdef HAVE_SETGROUPS
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006799 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006800#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00006801#ifdef HAVE_GETPGID
6802 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
6803#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006804#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00006805 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006806#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006807#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00006808 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006809#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006810#ifdef HAVE_WAIT3
6811 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
6812#endif /* HAVE_WAIT3 */
6813#ifdef HAVE_WAIT4
6814 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
6815#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00006816#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006817 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006818#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006819#ifdef HAVE_GETSID
6820 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
6821#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006822#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00006823 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006824#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006825#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006826 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006827#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006828#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006829 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006830#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006831#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006832 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006833#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006834 {"open", posix_open, METH_VARARGS, posix_open__doc__},
6835 {"close", posix_close, METH_VARARGS, posix_close__doc__},
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00006836 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006837 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
6838 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
6839 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
6840 {"read", posix_read, METH_VARARGS, posix_read__doc__},
6841 {"write", posix_write, METH_VARARGS, posix_write__doc__},
6842 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00006843 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006844#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00006845 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006846#endif
6847#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006848 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006849#endif
Neal Norwitz11690112002-07-30 01:08:28 +00006850#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006851 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
6852#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006853#ifdef HAVE_DEVICE_MACROS
6854 {"major", posix_major, METH_VARARGS, posix_major__doc__},
6855 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
6856 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
6857#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006858#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006859 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006860#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006861#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006862 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006863#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006864#ifdef HAVE_UNSETENV
6865 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
6866#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00006867#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006868 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00006869#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00006870#ifdef HAVE_FCHDIR
6871 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
6872#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00006873#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006874 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006875#endif
6876#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006877 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006878#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00006879#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00006880#ifdef WCOREDUMP
6881 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
6882#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006883#ifdef WIFCONTINUED
6884 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
6885#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00006886#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006887 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006888#endif /* WIFSTOPPED */
6889#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006890 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006891#endif /* WIFSIGNALED */
6892#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006893 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006894#endif /* WIFEXITED */
6895#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006896 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006897#endif /* WEXITSTATUS */
6898#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006899 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006900#endif /* WTERMSIG */
6901#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006902 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006903#endif /* WSTOPSIG */
6904#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00006905#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006906 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006907#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00006908#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006909 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006910#endif
Fred Drakec9680921999-12-13 16:37:25 +00006911#ifdef HAVE_CONFSTR
6912 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
6913#endif
6914#ifdef HAVE_SYSCONF
6915 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
6916#endif
6917#ifdef HAVE_FPATHCONF
6918 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
6919#endif
6920#ifdef HAVE_PATHCONF
6921 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
6922#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00006923 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006924#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00006925 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
6926#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00006927#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00006928 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00006929#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006930 #ifdef MS_WINDOWS
6931 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
6932 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006933 #ifdef __VMS
6934 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
6935 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006936 {NULL, NULL} /* Sentinel */
6937};
6938
6939
Barry Warsaw4a342091996-12-19 23:50:02 +00006940static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006941ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00006942{
Fred Drake4d1e64b2002-04-15 19:40:07 +00006943 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00006944}
6945
Guido van Rossumd48f2521997-12-05 22:19:34 +00006946#if defined(PYOS_OS2)
6947/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006948static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006949{
6950 APIRET rc;
6951 ULONG values[QSV_MAX+1];
6952 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00006953 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00006954
6955 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00006956 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006957 Py_END_ALLOW_THREADS
6958
6959 if (rc != NO_ERROR) {
6960 os2_error(rc);
6961 return -1;
6962 }
6963
Fred Drake4d1e64b2002-04-15 19:40:07 +00006964 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
6965 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
6966 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
6967 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
6968 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
6969 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
6970 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006971
6972 switch (values[QSV_VERSION_MINOR]) {
6973 case 0: ver = "2.00"; break;
6974 case 10: ver = "2.10"; break;
6975 case 11: ver = "2.11"; break;
6976 case 30: ver = "3.00"; break;
6977 case 40: ver = "4.00"; break;
6978 case 50: ver = "5.00"; break;
6979 default:
Tim Peters885d4572001-11-28 20:27:42 +00006980 PyOS_snprintf(tmp, sizeof(tmp),
6981 "%d-%d", values[QSV_VERSION_MAJOR],
6982 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006983 ver = &tmp[0];
6984 }
6985
6986 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006987 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006988 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006989
6990 /* Add Indicator of Which Drive was Used to Boot the System */
6991 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
6992 tmp[1] = ':';
6993 tmp[2] = '\0';
6994
Fred Drake4d1e64b2002-04-15 19:40:07 +00006995 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006996}
6997#endif
6998
Barry Warsaw4a342091996-12-19 23:50:02 +00006999static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007000all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007001{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007002#ifdef F_OK
7003 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007004#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007005#ifdef R_OK
7006 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007007#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007008#ifdef W_OK
7009 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007010#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007011#ifdef X_OK
7012 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007013#endif
Fred Drakec9680921999-12-13 16:37:25 +00007014#ifdef NGROUPS_MAX
7015 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7016#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007017#ifdef TMP_MAX
7018 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7019#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007020#ifdef WCONTINUED
7021 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7022#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007023#ifdef WNOHANG
7024 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007025#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007026#ifdef WUNTRACED
7027 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7028#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007029#ifdef O_RDONLY
7030 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7031#endif
7032#ifdef O_WRONLY
7033 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7034#endif
7035#ifdef O_RDWR
7036 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7037#endif
7038#ifdef O_NDELAY
7039 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7040#endif
7041#ifdef O_NONBLOCK
7042 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7043#endif
7044#ifdef O_APPEND
7045 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7046#endif
7047#ifdef O_DSYNC
7048 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7049#endif
7050#ifdef O_RSYNC
7051 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7052#endif
7053#ifdef O_SYNC
7054 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7055#endif
7056#ifdef O_NOCTTY
7057 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7058#endif
7059#ifdef O_CREAT
7060 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7061#endif
7062#ifdef O_EXCL
7063 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7064#endif
7065#ifdef O_TRUNC
7066 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7067#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007068#ifdef O_BINARY
7069 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7070#endif
7071#ifdef O_TEXT
7072 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7073#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007074#ifdef O_LARGEFILE
7075 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7076#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00007077#ifdef O_SHLOCK
7078 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
7079#endif
7080#ifdef O_EXLOCK
7081 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
7082#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007083
Tim Peters5aa91602002-01-30 05:46:57 +00007084/* MS Windows */
7085#ifdef O_NOINHERIT
7086 /* Don't inherit in child processes. */
7087 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7088#endif
7089#ifdef _O_SHORT_LIVED
7090 /* Optimize for short life (keep in memory). */
7091 /* MS forgot to define this one with a non-underscore form too. */
7092 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7093#endif
7094#ifdef O_TEMPORARY
7095 /* Automatically delete when last handle is closed. */
7096 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7097#endif
7098#ifdef O_RANDOM
7099 /* Optimize for random access. */
7100 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7101#endif
7102#ifdef O_SEQUENTIAL
7103 /* Optimize for sequential access. */
7104 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7105#endif
7106
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007107/* GNU extensions. */
7108#ifdef O_DIRECT
7109 /* Direct disk access. */
7110 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7111#endif
7112#ifdef O_DIRECTORY
7113 /* Must be a directory. */
7114 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7115#endif
7116#ifdef O_NOFOLLOW
7117 /* Do not follow links. */
7118 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7119#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007120
Barry Warsaw5676bd12003-01-07 20:57:09 +00007121 /* These come from sysexits.h */
7122#ifdef EX_OK
7123 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007124#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007125#ifdef EX_USAGE
7126 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007127#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007128#ifdef EX_DATAERR
7129 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007130#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007131#ifdef EX_NOINPUT
7132 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007133#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007134#ifdef EX_NOUSER
7135 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007136#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007137#ifdef EX_NOHOST
7138 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007139#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007140#ifdef EX_UNAVAILABLE
7141 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007142#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007143#ifdef EX_SOFTWARE
7144 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007145#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007146#ifdef EX_OSERR
7147 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007148#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007149#ifdef EX_OSFILE
7150 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007151#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007152#ifdef EX_CANTCREAT
7153 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007154#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007155#ifdef EX_IOERR
7156 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007157#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007158#ifdef EX_TEMPFAIL
7159 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007160#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007161#ifdef EX_PROTOCOL
7162 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007163#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007164#ifdef EX_NOPERM
7165 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007166#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007167#ifdef EX_CONFIG
7168 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007169#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007170#ifdef EX_NOTFOUND
7171 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007172#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007173
Guido van Rossum246bc171999-02-01 23:54:31 +00007174#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007175#if defined(PYOS_OS2) && defined(PYCC_GCC)
7176 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7177 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7178 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7179 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7180 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7181 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7182 if (ins(d, "P_PM", (long)P_PM)) return -1;
7183 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7184 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7185 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7186 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7187 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7188 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7189 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7190 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7191 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7192 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7193 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7194 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7195 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7196#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007197 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7198 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7199 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7200 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7201 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007202#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007203#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007204
Guido van Rossumd48f2521997-12-05 22:19:34 +00007205#if defined(PYOS_OS2)
7206 if (insertvalues(d)) return -1;
7207#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007208 return 0;
7209}
7210
7211
Tim Peters5aa91602002-01-30 05:46:57 +00007212#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007213#define INITFUNC initnt
7214#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007215
7216#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007217#define INITFUNC initos2
7218#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007219
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007220#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007221#define INITFUNC initposix
7222#define MODNAME "posix"
7223#endif
7224
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007225PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007226INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007227{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007228 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007229
Fred Drake4d1e64b2002-04-15 19:40:07 +00007230 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007231 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007232 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00007233 if (m == NULL)
7234 return;
Tim Peters5aa91602002-01-30 05:46:57 +00007235
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007236 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007237 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007238 Py_XINCREF(v);
7239 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007240 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007241 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007242
Fred Drake4d1e64b2002-04-15 19:40:07 +00007243 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007244 return;
7245
Fred Drake4d1e64b2002-04-15 19:40:07 +00007246 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007247 return;
7248
Fred Drake4d1e64b2002-04-15 19:40:07 +00007249 Py_INCREF(PyExc_OSError);
7250 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007251
Guido van Rossumb3d39562000-01-31 18:41:26 +00007252#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007253 if (posix_putenv_garbage == NULL)
7254 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007255#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007256
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007257 if (!initialized) {
7258 stat_result_desc.name = MODNAME ".stat_result";
7259 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7260 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7261 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
7262 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
7263 structseq_new = StatResultType.tp_new;
7264 StatResultType.tp_new = statresult_new;
7265
7266 statvfs_result_desc.name = MODNAME ".statvfs_result";
7267 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
7268 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007269 Py_INCREF((PyObject*) &StatResultType);
7270 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007271 Py_INCREF((PyObject*) &StatVFSResultType);
7272 PyModule_AddObject(m, "statvfs_result",
7273 (PyObject*) &StatVFSResultType);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007274 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007275
7276#ifdef __APPLE__
7277 /*
7278 * Step 2 of weak-linking support on Mac OS X.
7279 *
7280 * The code below removes functions that are not available on the
7281 * currently active platform.
7282 *
7283 * This block allow one to use a python binary that was build on
7284 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
7285 * OSX 10.4.
7286 */
7287#ifdef HAVE_FSTATVFS
7288 if (fstatvfs == NULL) {
7289 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
7290 return;
7291 }
7292 }
7293#endif /* HAVE_FSTATVFS */
7294
7295#ifdef HAVE_STATVFS
7296 if (statvfs == NULL) {
7297 if (PyObject_DelAttrString(m, "statvfs") == -1) {
7298 return;
7299 }
7300 }
7301#endif /* HAVE_STATVFS */
7302
7303# ifdef HAVE_LCHOWN
7304 if (lchown == NULL) {
7305 if (PyObject_DelAttrString(m, "lchown") == -1) {
7306 return;
7307 }
7308 }
7309#endif /* HAVE_LCHOWN */
7310
7311
7312#endif /* __APPLE__ */
7313
Guido van Rossumb6775db1994-08-01 11:34:53 +00007314}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007315
7316#ifdef __cplusplus
7317}
7318#endif