blob: f5b15d9cfa20a394bada1c72babd62f91715cdf3 [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
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000016#include "Python.h"
17#include "structseq.h"
18
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000019#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000020# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000021#endif /* defined(__VMS) */
22
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000023PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000024"This module provides access to operating system functionality that is\n\
25standardized by the C Standard and the POSIX standard (a thinly\n\
26disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000027corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000028
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000029#ifndef Py_USING_UNICODE
30/* This is used in signatures of functions. */
31#define Py_UNICODE void
32#endif
33
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000034#if defined(PYOS_OS2)
35#define INCL_DOS
36#define INCL_DOSERRORS
37#define INCL_DOSPROCESS
38#define INCL_NOPMAPI
39#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000040#if defined(PYCC_GCC)
41#include <ctype.h>
42#include <io.h>
43#include <stdio.h>
44#include <process.h>
45#include "osdefs.h"
46#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000047#endif
48
Guido van Rossumb6775db1994-08-01 11:34:53 +000049#include <sys/types.h>
50#include <sys/stat.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +000051
Guido van Rossum36bc6801995-06-14 22:54:23 +000052#ifdef HAVE_SYS_WAIT_H
53#include <sys/wait.h> /* For WNOHANG */
54#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000055
Guido van Rossuma376cc51996-12-05 23:43:35 +000056#ifdef HAVE_SIGNAL_H
57#include <signal.h>
58#endif
59
Guido van Rossumb6775db1994-08-01 11:34:53 +000060#ifdef HAVE_FCNTL_H
61#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000062#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000063
Guido van Rossuma6535fd2001-10-18 19:44:10 +000064#ifdef HAVE_GRP_H
65#include <grp.h>
66#endif
67
Barry Warsaw5676bd12003-01-07 20:57:09 +000068#ifdef HAVE_SYSEXITS_H
69#include <sysexits.h>
70#endif /* HAVE_SYSEXITS_H */
71
Guido van Rossuma4916fa1996-05-23 22:58:55 +000072/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000073/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000074#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000075#include <process.h>
76#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000077#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000078#define HAVE_GETCWD 1
79#define HAVE_OPENDIR 1
80#define HAVE_SYSTEM 1
81#if defined(__OS2__)
82#define HAVE_EXECV 1
83#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000084#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000085#include <process.h>
86#else
87#ifdef __BORLANDC__ /* Borland compiler */
88#define HAVE_EXECV 1
89#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000090#define HAVE_OPENDIR 1
91#define HAVE_PIPE 1
92#define HAVE_POPEN 1
93#define HAVE_SYSTEM 1
94#define HAVE_WAIT 1
95#else
96#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000097#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +000098#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000099#define HAVE_EXECV 1
100#define HAVE_PIPE 1
101#define HAVE_POPEN 1
102#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +0000103#define HAVE_CWAIT 1
Tim Peters11b23062003-04-23 02:39:17 +0000104#define HAVE_FSYNC 1
105#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000106#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000107#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
108/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000109#else /* all other compilers */
110/* Unix functions that the configure script doesn't check for */
111#define HAVE_EXECV 1
112#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000113#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
114#define HAVE_FORK1 1
115#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000116#define HAVE_GETCWD 1
117#define HAVE_GETEGID 1
118#define HAVE_GETEUID 1
119#define HAVE_GETGID 1
120#define HAVE_GETPPID 1
121#define HAVE_GETUID 1
122#define HAVE_KILL 1
123#define HAVE_OPENDIR 1
124#define HAVE_PIPE 1
125#define HAVE_POPEN 1
126#define HAVE_SYSTEM 1
127#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000128#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000129#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000130#endif /* _MSC_VER */
131#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000132#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000133#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000134
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000135#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000136
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000137#if defined(sun) && !defined(__SVR4)
138/* SunOS 4.1.4 doesn't have prototypes for these: */
139extern int rename(const char *, const char *);
140extern int pclose(FILE *);
141extern int fclose(FILE *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000142extern int fsync(int);
143extern int lstat(const char *, struct stat *);
144extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000145#endif
146
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000147#if defined(__sgi)&&_COMPILER_VERSION>=700
148/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
149 (default) */
150extern char *ctermid_r(char *);
151#endif
152
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000153#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000154#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000155extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000156#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000157#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000158extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000159#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000160extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000161#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000162#endif
163#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000164extern int chdir(char *);
165extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000166#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000167extern int chdir(const char *);
168extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000169#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000170#ifdef __BORLANDC__
171extern int chmod(const char *, int);
172#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000173extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000174#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000175extern int chown(const char *, uid_t, gid_t);
176extern char *getcwd(char *, int);
177extern char *strerror(int);
178extern int link(const char *, const char *);
179extern int rename(const char *, const char *);
180extern int stat(const char *, struct stat *);
181extern int unlink(const char *);
182extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000183#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000184extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000185#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000186#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000187extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000188#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000189#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000190
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000191#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000192
Guido van Rossumb6775db1994-08-01 11:34:53 +0000193#ifdef HAVE_UTIME_H
194#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000195#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000196
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000197#ifdef HAVE_SYS_UTIME_H
198#include <sys/utime.h>
199#define HAVE_UTIME_H /* pretend we do for the rest of this file */
200#endif /* HAVE_SYS_UTIME_H */
201
Guido van Rossumb6775db1994-08-01 11:34:53 +0000202#ifdef HAVE_SYS_TIMES_H
203#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000204#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205
206#ifdef HAVE_SYS_PARAM_H
207#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000208#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000209
210#ifdef HAVE_SYS_UTSNAME_H
211#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000212#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000213
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000214#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000215#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000216#define NAMLEN(dirent) strlen((dirent)->d_name)
217#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000218#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000219#include <direct.h>
220#define NAMLEN(dirent) strlen((dirent)->d_name)
221#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000222#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000223#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000224#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000225#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000227#endif
228#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000229#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000230#endif
231#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000233#endif
234#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000236#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000237#include <direct.h>
238#include <io.h>
239#include <process.h>
Tim Petersbc2e10e2002-03-03 23:17:02 +0000240#include "osdefs.h"
Tim Petersee66d0c2002-07-15 16:10:55 +0000241#define WIN32_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000242#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000243#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000244#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000245#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000246#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247
Guido van Rossumd48f2521997-12-05 22:19:34 +0000248#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000249#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000250#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000251
Tim Petersbc2e10e2002-03-03 23:17:02 +0000252#ifndef MAXPATHLEN
253#define MAXPATHLEN 1024
254#endif /* MAXPATHLEN */
255
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000256#ifdef UNION_WAIT
257/* Emulate some macros on systems that have a union instead of macros */
258
259#ifndef WIFEXITED
260#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
261#endif
262
263#ifndef WEXITSTATUS
264#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
265#endif
266
267#ifndef WTERMSIG
268#define WTERMSIG(u_wait) ((u_wait).w_termsig)
269#endif
270
271#endif /* UNION_WAIT */
272
Greg Wardb48bc172000-03-01 21:51:56 +0000273/* Don't use the "_r" form if we don't need it (also, won't have a
274 prototype for it, at least on Solaris -- maybe others as well?). */
275#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
276#define USE_CTERMID_R
277#endif
278
279#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
280#define USE_TMPNAM_R
281#endif
282
Fred Drake699f3522000-06-29 21:12:41 +0000283/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000284#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000285#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +0000286# define STAT _stati64
287# define FSTAT _fstati64
288# define STRUCT_STAT struct _stati64
289#else
290# define STAT stat
291# define FSTAT fstat
292# define STRUCT_STAT struct stat
293#endif
294
Tim Peters11b23062003-04-23 02:39:17 +0000295#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000296#include <sys/mkdev.h>
297#else
298#if defined(MAJOR_IN_SYSMACROS)
299#include <sys/sysmacros.h>
300#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000301#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
302#include <sys/mkdev.h>
303#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000304#endif
Fred Drake699f3522000-06-29 21:12:41 +0000305
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000306/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000307#ifdef WITH_NEXT_FRAMEWORK
308/* On Darwin/MacOSX a shared library or framework has no access to
309** environ directly, we must obtain it with _NSGetEnviron().
310*/
311#include <crt_externs.h>
312static char **environ;
313#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000314extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000315#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000316
Barry Warsaw53699e91996-12-10 23:23:01 +0000317static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000318convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000319{
Barry Warsaw53699e91996-12-10 23:23:01 +0000320 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000321 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000322 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000323 if (d == NULL)
324 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000325#ifdef WITH_NEXT_FRAMEWORK
326 if (environ == NULL)
327 environ = *_NSGetEnviron();
328#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000329 if (environ == NULL)
330 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000331 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000332 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000333 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000334 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000335 char *p = strchr(*e, '=');
336 if (p == NULL)
337 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000338 k = PyString_FromStringAndSize(*e, (int)(p-*e));
339 if (k == NULL) {
340 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000341 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000342 }
343 v = PyString_FromString(p+1);
344 if (v == NULL) {
345 PyErr_Clear();
346 Py_DECREF(k);
347 continue;
348 }
349 if (PyDict_GetItem(d, k) == NULL) {
350 if (PyDict_SetItem(d, k, v) != 0)
351 PyErr_Clear();
352 }
353 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000354 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000355 }
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000356#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000357 {
358 APIRET rc;
359 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
360
361 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000362 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000363 PyObject *v = PyString_FromString(buffer);
364 PyDict_SetItemString(d, "BEGINLIBPATH", v);
365 Py_DECREF(v);
366 }
367 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
368 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
369 PyObject *v = PyString_FromString(buffer);
370 PyDict_SetItemString(d, "ENDLIBPATH", v);
371 Py_DECREF(v);
372 }
373 }
374#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000375 return d;
376}
377
378
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000379/* Set a POSIX-specific error from errno, and return NULL */
380
Barry Warsawd58d7641998-07-23 16:14:40 +0000381static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000382posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000383{
Barry Warsawca74da41999-02-09 19:31:45 +0000384 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000385}
Barry Warsawd58d7641998-07-23 16:14:40 +0000386static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000387posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000388{
Barry Warsawca74da41999-02-09 19:31:45 +0000389 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000390}
391
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000392#ifdef Py_WIN_WIDE_FILENAMES
393static PyObject *
394posix_error_with_unicode_filename(Py_UNICODE* name)
395{
396 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
397}
398#endif /* Py_WIN_WIDE_FILENAMES */
399
400
Mark Hammondef8b6542001-05-13 08:04:26 +0000401static PyObject *
402posix_error_with_allocated_filename(char* name)
403{
404 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
405 PyMem_Free(name);
406 return rc;
407}
408
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000409#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000410static PyObject *
411win32_error(char* function, char* filename)
412{
Mark Hammond33a6da92000-08-15 00:46:38 +0000413 /* XXX We should pass the function name along in the future.
414 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000415 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000416 Windows error object, which is non-trivial.
417 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000418 errno = GetLastError();
419 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000420 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000421 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000422 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000423}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000424
425#ifdef Py_WIN_WIDE_FILENAMES
426static PyObject *
427win32_error_unicode(char* function, Py_UNICODE* filename)
428{
429 /* XXX - see win32_error for comments on 'function' */
430 errno = GetLastError();
431 if (filename)
432 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
433 else
434 return PyErr_SetFromWindowsErr(errno);
435}
436
437static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
438{
439 /* XXX Perhaps we should make this API an alias of
440 PyObject_Unicode() instead ?! */
441 if (PyUnicode_CheckExact(obj)) {
442 Py_INCREF(obj);
443 return obj;
444 }
445 if (PyUnicode_Check(obj)) {
446 /* For a Unicode subtype that's not a Unicode object,
447 return a true Unicode object with the same data. */
448 return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),
449 PyUnicode_GET_SIZE(obj));
450 }
Tim Peters11b23062003-04-23 02:39:17 +0000451 return PyUnicode_FromEncodedObject(obj,
452 Py_FileSystemDefaultEncoding,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000453 "strict");
454}
455
456#endif /* Py_WIN_WIDE_FILENAMES */
457
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000458#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000459
Guido van Rossumd48f2521997-12-05 22:19:34 +0000460#if defined(PYOS_OS2)
461/**********************************************************************
462 * Helper Function to Trim and Format OS/2 Messages
463 **********************************************************************/
464 static void
465os2_formatmsg(char *msgbuf, int msglen, char *reason)
466{
467 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
468
469 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
470 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
471
472 while (lastc > msgbuf && isspace(*lastc))
473 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
474 }
475
476 /* Add Optional Reason Text */
477 if (reason) {
478 strcat(msgbuf, " : ");
479 strcat(msgbuf, reason);
480 }
481}
482
483/**********************************************************************
484 * Decode an OS/2 Operating System Error Code
485 *
486 * A convenience function to lookup an OS/2 error code and return a
487 * text message we can use to raise a Python exception.
488 *
489 * Notes:
490 * The messages for errors returned from the OS/2 kernel reside in
491 * the file OSO001.MSG in the \OS2 directory hierarchy.
492 *
493 **********************************************************************/
494 static char *
495os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
496{
497 APIRET rc;
498 ULONG msglen;
499
500 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
501 Py_BEGIN_ALLOW_THREADS
502 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
503 errorcode, "oso001.msg", &msglen);
504 Py_END_ALLOW_THREADS
505
506 if (rc == NO_ERROR)
507 os2_formatmsg(msgbuf, msglen, reason);
508 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000509 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000510 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000511
512 return msgbuf;
513}
514
515/* Set an OS/2-specific error and return NULL. OS/2 kernel
516 errors are not in a global variable e.g. 'errno' nor are
517 they congruent with posix error numbers. */
518
519static PyObject * os2_error(int code)
520{
521 char text[1024];
522 PyObject *v;
523
524 os2_strerror(text, sizeof(text), code, "");
525
526 v = Py_BuildValue("(is)", code, text);
527 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000528 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000529 Py_DECREF(v);
530 }
531 return NULL; /* Signal to Python that an Exception is Pending */
532}
533
534#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000535
536/* POSIX generic methods */
537
Barry Warsaw53699e91996-12-10 23:23:01 +0000538static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000539posix_fildes(PyObject *fdobj, int (*func)(int))
540{
541 int fd;
542 int res;
543 fd = PyObject_AsFileDescriptor(fdobj);
544 if (fd < 0)
545 return NULL;
546 Py_BEGIN_ALLOW_THREADS
547 res = (*func)(fd);
548 Py_END_ALLOW_THREADS
549 if (res < 0)
550 return posix_error();
551 Py_INCREF(Py_None);
552 return Py_None;
553}
Guido van Rossum21142a01999-01-08 21:05:37 +0000554
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000555#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000556static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000557unicode_file_names(void)
558{
559 static int canusewide = -1;
560 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000561 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000562 the Windows NT family. */
563 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
564 }
565 return canusewide;
566}
567#endif
Tim Peters11b23062003-04-23 02:39:17 +0000568
Guido van Rossum21142a01999-01-08 21:05:37 +0000569static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000570posix_1str(PyObject *args, char *format, int (*func)(const char*),
571 char *wformat, int (*wfunc)(const Py_UNICODE*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000572{
Mark Hammondef8b6542001-05-13 08:04:26 +0000573 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000574 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000575#ifdef Py_WIN_WIDE_FILENAMES
576 if (unicode_file_names()) {
577 PyUnicodeObject *po;
578 if (PyArg_ParseTuple(args, wformat, &po)) {
579 Py_BEGIN_ALLOW_THREADS
580 /* PyUnicode_AS_UNICODE OK without thread
581 lock as it is a simple dereference. */
582 res = (*wfunc)(PyUnicode_AS_UNICODE(po));
583 Py_END_ALLOW_THREADS
584 if (res < 0)
Mark Hammondd3890362002-10-03 07:24:48 +0000585 return posix_error_with_unicode_filename(PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000586 Py_INCREF(Py_None);
587 return Py_None;
588 }
589 /* Drop the argument parsing error as narrow
590 strings are also valid. */
591 PyErr_Clear();
592 }
593#else
594 /* Platforms that don't support Unicode filenames
595 shouldn't be passing these extra params */
596 assert(wformat==NULL && wfunc == NULL);
597#endif
598
Tim Peters5aa91602002-01-30 05:46:57 +0000599 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000600 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000601 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000602 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000603 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000604 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000605 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000606 return posix_error_with_allocated_filename(path1);
607 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000608 Py_INCREF(Py_None);
609 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000610}
611
Barry Warsaw53699e91996-12-10 23:23:01 +0000612static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000613posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000614 char *format,
615 int (*func)(const char *, const char *),
616 char *wformat,
617 int (*wfunc)(const Py_UNICODE *, const Py_UNICODE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000618{
Mark Hammondef8b6542001-05-13 08:04:26 +0000619 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000620 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000621#ifdef Py_WIN_WIDE_FILENAMES
622 if (unicode_file_names()) {
623 PyObject *po1;
624 PyObject *po2;
625 if (PyArg_ParseTuple(args, wformat, &po1, &po2)) {
626 if (PyUnicode_Check(po1) || PyUnicode_Check(po2)) {
627 PyObject *wpath1;
628 PyObject *wpath2;
629 wpath1 = _PyUnicode_FromFileSystemEncodedObject(po1);
630 wpath2 = _PyUnicode_FromFileSystemEncodedObject(po2);
631 if (!wpath1 || !wpath2) {
632 Py_XDECREF(wpath1);
633 Py_XDECREF(wpath2);
634 return NULL;
635 }
636 Py_BEGIN_ALLOW_THREADS
637 /* PyUnicode_AS_UNICODE OK without thread
638 lock as it is a simple dereference. */
639 res = (*wfunc)(PyUnicode_AS_UNICODE(wpath1),
640 PyUnicode_AS_UNICODE(wpath2));
641 Py_END_ALLOW_THREADS
642 Py_XDECREF(wpath1);
643 Py_XDECREF(wpath2);
644 if (res != 0)
645 return posix_error();
646 Py_INCREF(Py_None);
647 return Py_None;
648 }
649 /* Else flow through as neither is Unicode. */
650 }
651 /* Drop the argument parsing error as narrow
652 strings are also valid. */
653 PyErr_Clear();
654 }
655#else
656 /* Platforms that don't support Unicode filenames
657 shouldn't be passing these extra params */
658 assert(wformat==NULL && wfunc == NULL);
659#endif
660
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
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000677PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000678"stat_result: Result from stat or lstat.\n\n\
679This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000680 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000681or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
682\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000683Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000684they are available as attributes only.\n\
685\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000686See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000687
688static PyStructSequence_Field stat_result_fields[] = {
689 {"st_mode", "protection bits"},
690 {"st_ino", "inode"},
691 {"st_dev", "device"},
692 {"st_nlink", "number of hard links"},
693 {"st_uid", "user ID of owner"},
694 {"st_gid", "group ID of owner"},
695 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000696 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
697 {NULL, "integer time of last access"},
698 {NULL, "integer time of last modification"},
699 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000700 {"st_atime", "time of last access"},
701 {"st_mtime", "time of last modification"},
702 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000703#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000704 {"st_blksize", "blocksize for filesystem I/O"},
705#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000706#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000707 {"st_blocks", "number of blocks allocated"},
708#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000709#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000710 {"st_rdev", "device type (if inode device)"},
711#endif
712 {0}
713};
714
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000715#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000716#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000717#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000718#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000719#endif
720
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000721#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000722#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
723#else
724#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
725#endif
726
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000727#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000728#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
729#else
730#define ST_RDEV_IDX ST_BLOCKS_IDX
731#endif
732
733static PyStructSequence_Desc stat_result_desc = {
734 "stat_result", /* name */
735 stat_result__doc__, /* doc */
736 stat_result_fields,
737 10
738};
739
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000740PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000741"statvfs_result: Result from statvfs or fstatvfs.\n\n\
742This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000743 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000744or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000745\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000746See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000747
748static PyStructSequence_Field statvfs_result_fields[] = {
749 {"f_bsize", },
750 {"f_frsize", },
751 {"f_blocks", },
752 {"f_bfree", },
753 {"f_bavail", },
754 {"f_files", },
755 {"f_ffree", },
756 {"f_favail", },
757 {"f_flag", },
758 {"f_namemax",},
759 {0}
760};
761
762static PyStructSequence_Desc statvfs_result_desc = {
763 "statvfs_result", /* name */
764 statvfs_result__doc__, /* doc */
765 statvfs_result_fields,
766 10
767};
768
769static PyTypeObject StatResultType;
770static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000771static newfunc structseq_new;
772
773static PyObject *
774statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
775{
776 PyStructSequence *result;
777 int i;
778
779 result = (PyStructSequence*)structseq_new(type, args, kwds);
780 if (!result)
781 return NULL;
782 /* If we have been initialized from a tuple,
783 st_?time might be set to None. Initialize it
784 from the int slots. */
785 for (i = 7; i <= 9; i++) {
786 if (result->ob_item[i+3] == Py_None) {
787 Py_DECREF(Py_None);
788 Py_INCREF(result->ob_item[i]);
789 result->ob_item[i+3] = result->ob_item[i];
790 }
791 }
792 return (PyObject*)result;
793}
794
795
796
797/* If true, st_?time is float. */
798static int _stat_float_times = 0;
799
800PyDoc_STRVAR(stat_float_times__doc__,
801"stat_float_times([newval]) -> oldval\n\n\
802Determine whether os.[lf]stat represents time stamps as float objects.\n\
803If newval is True, future calls to stat() return floats, if it is False,\n\
804future calls return ints. \n\
805If newval is omitted, return the current setting.\n");
806
807static PyObject*
808stat_float_times(PyObject* self, PyObject *args)
809{
810 int newval = -1;
811 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
812 return NULL;
813 if (newval == -1)
814 /* Return old value */
815 return PyBool_FromLong(_stat_float_times);
816 _stat_float_times = newval;
817 Py_INCREF(Py_None);
818 return Py_None;
819}
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000820
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000821static void
822fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
823{
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000824 PyObject *fval,*ival;
825#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000826 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000827#else
828 ival = PyInt_FromLong((long)sec);
829#endif
830 if (_stat_float_times) {
831 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
832 } else {
833 fval = ival;
834 Py_INCREF(fval);
835 }
836 PyStructSequence_SET_ITEM(v, index, ival);
837 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000838}
839
Tim Peters5aa91602002-01-30 05:46:57 +0000840/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +0000841 (used by posix_stat() and posix_fstat()) */
842static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000843_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000844{
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000845 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000846 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000847 if (v == NULL)
848 return NULL;
849
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000850 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000851#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000852 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000853 PyLong_FromLongLong((PY_LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000854#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000855 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000856#endif
857#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +0000858 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000859 PyLong_FromLongLong((PY_LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000860#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000861 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000862#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000863 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
864 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
865 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000866#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000867 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000868 PyLong_FromLongLong((PY_LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000869#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000870 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000871#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000872
873#ifdef HAVE_STAT_TV_NSEC
874 ansec = st.st_atim.tv_nsec;
875 mnsec = st.st_mtim.tv_nsec;
876 cnsec = st.st_ctim.tv_nsec;
Fred Drake699f3522000-06-29 21:12:41 +0000877#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000878 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000879#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000880 fill_time(v, 7, st.st_atime, ansec);
881 fill_time(v, 8, st.st_mtime, mnsec);
882 fill_time(v, 9, st.st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000883
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000884#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +0000885 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000886 PyInt_FromLong((long)st.st_blksize));
887#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000888#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +0000889 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000890 PyInt_FromLong((long)st.st_blocks));
891#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000892#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000893 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
894 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000895#endif
896
897 if (PyErr_Occurred()) {
898 Py_DECREF(v);
899 return NULL;
900 }
901
902 return v;
903}
904
Barry Warsaw53699e91996-12-10 23:23:01 +0000905static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000906posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000907 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000908#ifdef __VMS
909 int (*statfunc)(const char *, STRUCT_STAT *, ...),
910#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000911 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000912#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000913 char *wformat,
914 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000915{
Fred Drake699f3522000-06-29 21:12:41 +0000916 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +0000917 char *path = NULL; /* pass this to stat; do not free() it */
918 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000919 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000920
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000921#ifdef MS_WINDOWS
Tim Peters500bd032001-12-19 19:05:01 +0000922 int pathlen;
923 char pathcopy[MAX_PATH];
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000924#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000925
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000926
927#ifdef Py_WIN_WIDE_FILENAMES
928 /* If on wide-character-capable OS see if argument
929 is Unicode and if so use wide API. */
930 if (unicode_file_names()) {
931 PyUnicodeObject *po;
932 if (PyArg_ParseTuple(args, wformat, &po)) {
933 Py_UNICODE wpath[MAX_PATH+1];
934 pathlen = wcslen(PyUnicode_AS_UNICODE(po));
935 /* the library call can blow up if the file name is too long! */
936 if (pathlen > MAX_PATH) {
937 errno = ENAMETOOLONG;
938 return posix_error();
939 }
940 wcscpy(wpath, PyUnicode_AS_UNICODE(po));
941 /* Remove trailing slash or backslash, unless it's the current
942 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
943 */
944 if (pathlen > 0 &&
945 (wpath[pathlen-1]== L'\\' || wpath[pathlen-1] == L'/')) {
946 /* It does end with a slash -- exempt the root drive cases. */
947 /* XXX UNC root drives should also be exempted? */
948 if (pathlen == 1 || (pathlen == 3 && wpath[1] == L':'))
949 /* leave it alone */;
950 else {
951 /* nuke the trailing backslash */
952 wpath[pathlen-1] = L'\0';
953 }
954 }
955 Py_BEGIN_ALLOW_THREADS
956 /* PyUnicode_AS_UNICODE result OK without
957 thread lock as it is a simple dereference. */
958 res = wstatfunc(wpath, &st);
959 Py_END_ALLOW_THREADS
960 if (res != 0)
961 return posix_error_with_unicode_filename(wpath);
962 return _pystat_fromstructstat(st);
963 }
964 /* Drop the argument parsing error as narrow strings
965 are also valid. */
966 PyErr_Clear();
967 }
968#endif
969
Tim Peters5aa91602002-01-30 05:46:57 +0000970 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000971 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000972 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +0000973 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000974
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000975#ifdef MS_WINDOWS
Guido van Rossumace88ae2000-04-21 18:54:45 +0000976 pathlen = strlen(path);
977 /* the library call can blow up if the file name is too long! */
978 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +0000979 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000980 errno = ENAMETOOLONG;
981 return posix_error();
982 }
983
Tim Peters500bd032001-12-19 19:05:01 +0000984 /* Remove trailing slash or backslash, unless it's the current
985 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
986 */
987 if (pathlen > 0 &&
988 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
989 /* It does end with a slash -- exempt the root drive cases. */
990 /* XXX UNC root drives should also be exempted? */
991 if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
992 /* leave it alone */;
993 else {
994 /* nuke the trailing backslash */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000995 strncpy(pathcopy, path, pathlen);
Tim Peters500bd032001-12-19 19:05:01 +0000996 pathcopy[pathlen-1] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +0000997 path = pathcopy;
998 }
999 }
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001000#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +00001001
Barry Warsaw53699e91996-12-10 23:23:01 +00001002 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001003 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001004 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001005 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +00001006 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +00001007
Tim Peters500bd032001-12-19 19:05:01 +00001008 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +00001009 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001010}
1011
1012
1013/* POSIX methods */
1014
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001015PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001016"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001017Use the real uid/gid to test for access to a path. Note that most\n\
1018operations will use the effective uid/gid, therefore this routine can\n\
1019be used in a suid/sgid environment to test if the invoking user has the\n\
1020specified access to the path. The mode argument can be F_OK to test\n\
1021existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001022
1023static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001024posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001025{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001026 char *path;
1027 int mode;
1028 int res;
1029
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001030#ifdef Py_WIN_WIDE_FILENAMES
1031 if (unicode_file_names()) {
1032 PyUnicodeObject *po;
1033 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1034 Py_BEGIN_ALLOW_THREADS
1035 /* PyUnicode_AS_UNICODE OK without thread lock as
1036 it is a simple dereference. */
1037 res = _waccess(PyUnicode_AS_UNICODE(po), mode);
1038 Py_END_ALLOW_THREADS
1039 return(PyBool_FromLong(res == 0));
1040 }
1041 /* Drop the argument parsing error as narrow strings
1042 are also valid. */
1043 PyErr_Clear();
1044 }
1045#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001046 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001047 return NULL;
1048 Py_BEGIN_ALLOW_THREADS
1049 res = access(path, mode);
1050 Py_END_ALLOW_THREADS
Guido van Rossum674deb22002-09-01 15:06:28 +00001051 return(PyBool_FromLong(res == 0));
Guido van Rossum94f6f721999-01-06 18:42:14 +00001052}
1053
Guido van Rossumd371ff11999-01-25 16:12:23 +00001054#ifndef F_OK
1055#define F_OK 0
1056#endif
1057#ifndef R_OK
1058#define R_OK 4
1059#endif
1060#ifndef W_OK
1061#define W_OK 2
1062#endif
1063#ifndef X_OK
1064#define X_OK 1
1065#endif
1066
1067#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001068PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001069"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001070Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001071
1072static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001073posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001074{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001075 int id;
1076 char *ret;
1077
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001078 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001079 return NULL;
1080
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001081#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001082 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001083 if (id == 0) {
1084 ret = ttyname();
1085 }
1086 else {
1087 ret = NULL;
1088 }
1089#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001090 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001091#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001092 if (ret == NULL)
1093 return(posix_error());
1094 return(PyString_FromString(ret));
1095}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001096#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001097
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001098#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001099PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001100"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001101Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001102
1103static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001104posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001105{
1106 char *ret;
1107 char buffer[L_ctermid];
1108
Greg Wardb48bc172000-03-01 21:51:56 +00001109#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001110 ret = ctermid_r(buffer);
1111#else
1112 ret = ctermid(buffer);
1113#endif
1114 if (ret == NULL)
1115 return(posix_error());
1116 return(PyString_FromString(buffer));
1117}
1118#endif
1119
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001120PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001121"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001122Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001123
Barry Warsaw53699e91996-12-10 23:23:01 +00001124static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001125posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001126{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001127#ifdef MS_WINDOWS
1128 return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir);
1129#elif defined(PYOS_OS2) && defined(PYCC_GCC)
1130 return posix_1str(args, "et:chdir", _chdir2, NULL, NULL);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001131#elif defined(__VMS)
Tim Peters11b23062003-04-23 02:39:17 +00001132 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001133 NULL, NULL);
1134#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001135 return posix_1str(args, "et:chdir", chdir, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001136#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001137}
1138
Fred Drake4d1e64b2002-04-15 19:40:07 +00001139#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001140PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001141"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001142Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001143opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001144
1145static PyObject *
1146posix_fchdir(PyObject *self, PyObject *fdobj)
1147{
1148 return posix_fildes(fdobj, fchdir);
1149}
1150#endif /* HAVE_FCHDIR */
1151
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001152
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001153PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001154"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001155Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001156
Barry Warsaw53699e91996-12-10 23:23:01 +00001157static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001158posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001159{
Mark Hammondef8b6542001-05-13 08:04:26 +00001160 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001161 int i;
1162 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001163 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001164 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001165 return NULL;
1166 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001167 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001168 Py_END_ALLOW_THREADS
1169 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001170 return posix_error_with_allocated_filename(path);
1171 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001172 Py_INCREF(Py_None);
1173 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001174}
1175
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001176
Martin v. Löwis244edc82001-10-04 22:44:26 +00001177#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001178PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001179"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001180Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001181
1182static PyObject *
1183posix_chroot(PyObject *self, PyObject *args)
1184{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001185 return posix_1str(args, "et:chroot", chroot, NULL, NULL);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001186}
1187#endif
1188
Guido van Rossum21142a01999-01-08 21:05:37 +00001189#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001190PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001191"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001192force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001193
1194static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001195posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001196{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001197 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001198}
1199#endif /* HAVE_FSYNC */
1200
1201#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001202
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001203#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001204extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1205#endif
1206
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001207PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001208"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001209force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001210 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001211
1212static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001213posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001214{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001215 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001216}
1217#endif /* HAVE_FDATASYNC */
1218
1219
Fredrik Lundh10723342000-07-10 16:38:09 +00001220#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001221PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001222"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001223Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001224
Barry Warsaw53699e91996-12-10 23:23:01 +00001225static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001226posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001227{
Mark Hammondef8b6542001-05-13 08:04:26 +00001228 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001229 int uid, gid;
1230 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001231 if (!PyArg_ParseTuple(args, "etii:chown",
1232 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001233 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001234 return NULL;
1235 Py_BEGIN_ALLOW_THREADS
1236 res = chown(path, (uid_t) uid, (gid_t) gid);
1237 Py_END_ALLOW_THREADS
1238 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001239 return posix_error_with_allocated_filename(path);
1240 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001241 Py_INCREF(Py_None);
1242 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001243}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001244#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001245
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001246#ifdef HAVE_LCHOWN
1247PyDoc_STRVAR(posix_lchown__doc__,
1248"lchown(path, uid, gid)\n\n\
1249Change the owner and group id of path to the numeric uid and gid.\n\
1250This function will not follow symbolic links.");
1251
1252static PyObject *
1253posix_lchown(PyObject *self, PyObject *args)
1254{
1255 char *path = NULL;
1256 int uid, gid;
1257 int res;
1258 if (!PyArg_ParseTuple(args, "etii:lchown",
1259 Py_FileSystemDefaultEncoding, &path,
1260 &uid, &gid))
1261 return NULL;
1262 Py_BEGIN_ALLOW_THREADS
1263 res = lchown(path, (uid_t) uid, (gid_t) gid);
1264 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001265 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001266 return posix_error_with_allocated_filename(path);
1267 PyMem_Free(path);
1268 Py_INCREF(Py_None);
1269 return Py_None;
1270}
1271#endif /* HAVE_LCHOWN */
1272
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001273
Guido van Rossum36bc6801995-06-14 22:54:23 +00001274#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001275PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001276"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001277Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001278
Barry Warsaw53699e91996-12-10 23:23:01 +00001279static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001280posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001281{
1282 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001283 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001284
Barry Warsaw53699e91996-12-10 23:23:01 +00001285 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001286#if defined(PYOS_OS2) && defined(PYCC_GCC)
1287 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001288#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001289 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001290#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001291 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001292 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001293 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001294 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001295}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001296
Walter Dörwald3b918c32002-11-21 20:18:46 +00001297#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001298PyDoc_STRVAR(posix_getcwdu__doc__,
1299"getcwdu() -> path\n\n\
1300Return a unicode string representing the current working directory.");
1301
1302static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001303posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001304{
1305 char buf[1026];
1306 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001307
1308#ifdef Py_WIN_WIDE_FILENAMES
1309 if (unicode_file_names()) {
1310 wchar_t *wres;
1311 wchar_t wbuf[1026];
1312 Py_BEGIN_ALLOW_THREADS
1313 wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
1314 Py_END_ALLOW_THREADS
1315 if (wres == NULL)
1316 return posix_error();
1317 return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
1318 }
1319#endif
1320
1321 Py_BEGIN_ALLOW_THREADS
1322#if defined(PYOS_OS2) && defined(PYCC_GCC)
1323 res = _getcwd2(buf, sizeof buf);
1324#else
1325 res = getcwd(buf, sizeof buf);
1326#endif
1327 Py_END_ALLOW_THREADS
1328 if (res == NULL)
1329 return posix_error();
1330 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1331}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001332#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00001333#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001334
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001335
Guido van Rossumb6775db1994-08-01 11:34:53 +00001336#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001337PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001338"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001339Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001340
Barry Warsaw53699e91996-12-10 23:23:01 +00001341static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001342posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001343{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001344 return posix_2str(args, "etet:link", link, NULL, NULL);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001345}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001346#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001347
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001348
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001349PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001350"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001351Return a list containing the names of the entries in the directory.\n\
1352\n\
1353 path: path of directory to list\n\
1354\n\
1355The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001356entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001357
Barry Warsaw53699e91996-12-10 23:23:01 +00001358static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001359posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001360{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001361 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001362 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001363#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001364
Barry Warsaw53699e91996-12-10 23:23:01 +00001365 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001366 HANDLE hFindFile;
1367 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001368 /* MAX_PATH characters could mean a bigger encoded string */
1369 char namebuf[MAX_PATH*2+5];
1370 char *bufptr = namebuf;
1371 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001372
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001373#ifdef Py_WIN_WIDE_FILENAMES
1374 /* If on wide-character-capable OS see if argument
1375 is Unicode and if so use wide API. */
1376 if (unicode_file_names()) {
1377 PyUnicodeObject *po;
1378 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1379 WIN32_FIND_DATAW wFileData;
1380 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1381 Py_UNICODE wch;
1382 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1383 wnamebuf[MAX_PATH] = L'\0';
1384 len = wcslen(wnamebuf);
1385 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1386 if (wch != L'/' && wch != L'\\' && wch != L':')
1387 wnamebuf[len++] = L'/';
1388 wcscpy(wnamebuf + len, L"*.*");
1389 if ((d = PyList_New(0)) == NULL)
1390 return NULL;
1391 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1392 if (hFindFile == INVALID_HANDLE_VALUE) {
1393 errno = GetLastError();
1394 if (errno == ERROR_FILE_NOT_FOUND) {
1395 return d;
1396 }
1397 Py_DECREF(d);
1398 return win32_error_unicode("FindFirstFileW", wnamebuf);
1399 }
1400 do {
1401 if (wFileData.cFileName[0] == L'.' &&
1402 (wFileData.cFileName[1] == L'\0' ||
1403 wFileData.cFileName[1] == L'.' &&
1404 wFileData.cFileName[2] == L'\0'))
1405 continue;
1406 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1407 if (v == NULL) {
1408 Py_DECREF(d);
1409 d = NULL;
1410 break;
1411 }
1412 if (PyList_Append(d, v) != 0) {
1413 Py_DECREF(v);
1414 Py_DECREF(d);
1415 d = NULL;
1416 break;
1417 }
1418 Py_DECREF(v);
1419 } while (FindNextFileW(hFindFile, &wFileData) == TRUE);
1420
1421 if (FindClose(hFindFile) == FALSE) {
1422 Py_DECREF(d);
1423 return win32_error_unicode("FindClose", wnamebuf);
1424 }
1425 return d;
1426 }
1427 /* Drop the argument parsing error as narrow strings
1428 are also valid. */
1429 PyErr_Clear();
1430 }
1431#endif
1432
Tim Peters5aa91602002-01-30 05:46:57 +00001433 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001434 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001435 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001436 if (len > 0) {
1437 char ch = namebuf[len-1];
1438 if (ch != SEP && ch != ALTSEP && ch != ':')
1439 namebuf[len++] = '/';
1440 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001441 strcpy(namebuf + len, "*.*");
1442
Barry Warsaw53699e91996-12-10 23:23:01 +00001443 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001444 return NULL;
1445
1446 hFindFile = FindFirstFile(namebuf, &FileData);
1447 if (hFindFile == INVALID_HANDLE_VALUE) {
1448 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001449 if (errno == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001450 return d;
1451 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001452 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001453 }
1454 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001455 if (FileData.cFileName[0] == '.' &&
1456 (FileData.cFileName[1] == '\0' ||
1457 FileData.cFileName[1] == '.' &&
1458 FileData.cFileName[2] == '\0'))
1459 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001460 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001461 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001462 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001463 d = NULL;
1464 break;
1465 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001466 if (PyList_Append(d, v) != 0) {
1467 Py_DECREF(v);
1468 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001469 d = NULL;
1470 break;
1471 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001472 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001473 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1474
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001475 if (FindClose(hFindFile) == FALSE) {
1476 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001477 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001478 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001479
1480 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001481
Tim Peters0bb44a42000-09-15 07:44:49 +00001482#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001483
1484#ifndef MAX_PATH
1485#define MAX_PATH CCHMAXPATH
1486#endif
1487 char *name, *pt;
1488 int len;
1489 PyObject *d, *v;
1490 char namebuf[MAX_PATH+5];
1491 HDIR hdir = 1;
1492 ULONG srchcnt = 1;
1493 FILEFINDBUF3 ep;
1494 APIRET rc;
1495
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001496 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001497 return NULL;
1498 if (len >= MAX_PATH) {
1499 PyErr_SetString(PyExc_ValueError, "path too long");
1500 return NULL;
1501 }
1502 strcpy(namebuf, name);
1503 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001504 if (*pt == ALTSEP)
1505 *pt = SEP;
1506 if (namebuf[len-1] != SEP)
1507 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001508 strcpy(namebuf + len, "*.*");
1509
1510 if ((d = PyList_New(0)) == NULL)
1511 return NULL;
1512
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001513 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1514 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001515 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001516 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1517 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1518 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001519
1520 if (rc != NO_ERROR) {
1521 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001522 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001523 }
1524
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001525 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001526 do {
1527 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001528 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001529 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001530
1531 strcpy(namebuf, ep.achName);
1532
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001533 /* Leave Case of Name Alone -- In Native Form */
1534 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001535
1536 v = PyString_FromString(namebuf);
1537 if (v == NULL) {
1538 Py_DECREF(d);
1539 d = NULL;
1540 break;
1541 }
1542 if (PyList_Append(d, v) != 0) {
1543 Py_DECREF(v);
1544 Py_DECREF(d);
1545 d = NULL;
1546 break;
1547 }
1548 Py_DECREF(v);
1549 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1550 }
1551
1552 return d;
1553#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001554
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001555 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001556 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001557 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001558 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00001559 int arg_is_unicode = 1;
1560
1561 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
1562 arg_is_unicode = 0;
1563 PyErr_Clear();
1564 }
1565 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001566 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001567 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001568 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001569 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001570 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001571 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001572 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001573 return NULL;
1574 }
1575 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001576 if (ep->d_name[0] == '.' &&
1577 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001578 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001579 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001580 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001581 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001582 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001583 d = NULL;
1584 break;
1585 }
Just van Rossum46c97842003-02-25 21:42:15 +00001586#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00001587 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00001588 PyObject *w;
1589
1590 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00001591 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00001592 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00001593 if (w != NULL) {
1594 Py_DECREF(v);
1595 v = w;
1596 }
1597 else {
1598 /* fall back to the original byte string, as
1599 discussed in patch #683592 */
1600 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00001601 }
Just van Rossum46c97842003-02-25 21:42:15 +00001602 }
1603#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001604 if (PyList_Append(d, v) != 0) {
1605 Py_DECREF(v);
1606 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001607 d = NULL;
1608 break;
1609 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001610 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001611 }
1612 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001613 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001614
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001615 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001616
Tim Peters0bb44a42000-09-15 07:44:49 +00001617#endif /* which OS */
1618} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001619
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001620#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001621/* A helper function for abspath on win32 */
1622static PyObject *
1623posix__getfullpathname(PyObject *self, PyObject *args)
1624{
1625 /* assume encoded strings wont more than double no of chars */
1626 char inbuf[MAX_PATH*2];
1627 char *inbufp = inbuf;
1628 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1629 char outbuf[MAX_PATH*2];
1630 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001631#ifdef Py_WIN_WIDE_FILENAMES
1632 if (unicode_file_names()) {
1633 PyUnicodeObject *po;
1634 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1635 Py_UNICODE woutbuf[MAX_PATH*2];
1636 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00001637 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001638 sizeof(woutbuf)/sizeof(woutbuf[0]),
1639 woutbuf, &wtemp))
1640 return win32_error("GetFullPathName", "");
1641 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1642 }
1643 /* Drop the argument parsing error as narrow strings
1644 are also valid. */
1645 PyErr_Clear();
1646 }
1647#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001648 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1649 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001650 &insize))
1651 return NULL;
1652 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1653 outbuf, &temp))
1654 return win32_error("GetFullPathName", inbuf);
1655 return PyString_FromString(outbuf);
1656} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001657#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001658
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001659PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001660"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001661Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001662
Barry Warsaw53699e91996-12-10 23:23:01 +00001663static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001664posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001665{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001666 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001667 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001668 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001669
1670#ifdef Py_WIN_WIDE_FILENAMES
1671 if (unicode_file_names()) {
1672 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00001673 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001674 Py_BEGIN_ALLOW_THREADS
1675 /* PyUnicode_AS_UNICODE OK without thread lock as
1676 it is a simple dereference. */
1677 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1678 Py_END_ALLOW_THREADS
1679 if (res < 0)
1680 return posix_error();
1681 Py_INCREF(Py_None);
1682 return Py_None;
1683 }
1684 /* Drop the argument parsing error as narrow strings
1685 are also valid. */
1686 PyErr_Clear();
1687 }
1688#endif
1689
Tim Peters5aa91602002-01-30 05:46:57 +00001690 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001691 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001692 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001693 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001694#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001695 res = mkdir(path);
1696#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001697 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001698#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001699 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001700 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001701 return posix_error_with_allocated_filename(path);
1702 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001703 Py_INCREF(Py_None);
1704 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001705}
1706
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001707
Guido van Rossumb6775db1994-08-01 11:34:53 +00001708#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001709#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1710#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1711#include <sys/resource.h>
1712#endif
1713#endif
1714
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001715PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001716"nice(inc) -> new_priority\n\n\
1717Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001718
Barry Warsaw53699e91996-12-10 23:23:01 +00001719static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001720posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001721{
1722 int increment, value;
1723
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001724 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001725 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001726
1727 /* There are two flavours of 'nice': one that returns the new
1728 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001729 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1730 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001731
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001732 If we are of the nice family that returns the new priority, we
1733 need to clear errno before the call, and check if errno is filled
1734 before calling posix_error() on a returnvalue of -1, because the
1735 -1 may be the actual new priority! */
1736
1737 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001738 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001739#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001740 if (value == 0)
1741 value = getpriority(PRIO_PROCESS, 0);
1742#endif
1743 if (value == -1 && errno != 0)
1744 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001745 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001746 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001747}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001748#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001749
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001750
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001751PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001752"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001753Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001754
Barry Warsaw53699e91996-12-10 23:23:01 +00001755static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001756posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001757{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001758#ifdef MS_WINDOWS
1759 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
1760#else
1761 return posix_2str(args, "etet:rename", rename, NULL, NULL);
1762#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001763}
1764
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001765
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001766PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001767"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001768Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001769
Barry Warsaw53699e91996-12-10 23:23:01 +00001770static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001771posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001772{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001773#ifdef MS_WINDOWS
1774 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
1775#else
1776 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
1777#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001778}
1779
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001780
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001781PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001782"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001783Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001784
Barry Warsaw53699e91996-12-10 23:23:01 +00001785static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001786posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001787{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001788#ifdef MS_WINDOWS
1789 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", _wstati64);
1790#else
1791 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
1792#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001793}
1794
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001795
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001796#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001797PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001798"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001799Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001800
Barry Warsaw53699e91996-12-10 23:23:01 +00001801static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001802posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001803{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001804 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001805 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001806 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001807 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001808 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001809 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001810 Py_END_ALLOW_THREADS
1811 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001812}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001813#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001814
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001815
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001816PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001817"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001818Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001819
Barry Warsaw53699e91996-12-10 23:23:01 +00001820static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001821posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001822{
1823 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001824 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001825 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001826 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001827 if (i < 0)
1828 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001829 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001830}
1831
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001832
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001833PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001834"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001835Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001836
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001837PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001838"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001839Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001840
Barry Warsaw53699e91996-12-10 23:23:01 +00001841static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001842posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001843{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001844#ifdef MS_WINDOWS
1845 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
1846#else
1847 return posix_1str(args, "et:remove", unlink, NULL, NULL);
1848#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001849}
1850
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001851
Guido van Rossumb6775db1994-08-01 11:34:53 +00001852#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001853PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001854"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001855Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001856
Barry Warsaw53699e91996-12-10 23:23:01 +00001857static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001858posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001859{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001860 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001861 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001862
Barry Warsaw53699e91996-12-10 23:23:01 +00001863 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001864 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001865 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001866 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001867 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001868 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001869 u.sysname,
1870 u.nodename,
1871 u.release,
1872 u.version,
1873 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001874}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001875#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001876
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001877static int
1878extract_time(PyObject *t, long* sec, long* usec)
1879{
1880 long intval;
1881 if (PyFloat_Check(t)) {
1882 double tval = PyFloat_AsDouble(t);
1883 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
1884 if (!intobj)
1885 return -1;
1886 intval = PyInt_AsLong(intobj);
1887 Py_DECREF(intobj);
1888 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00001889 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001890 if (*usec < 0)
1891 /* If rounding gave us a negative number,
1892 truncate. */
1893 *usec = 0;
1894 return 0;
1895 }
1896 intval = PyInt_AsLong(t);
1897 if (intval == -1 && PyErr_Occurred())
1898 return -1;
1899 *sec = intval;
1900 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00001901 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001902}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001903
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001904PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001905"utime(path, (atime, utime))\n\
1906utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001907Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001908second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001909
Barry Warsaw53699e91996-12-10 23:23:01 +00001910static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001911posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001912{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001913 char *path;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001914 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001915 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001916 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001917
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001918#if defined(HAVE_UTIMES)
1919 struct timeval buf[2];
1920#define ATIME buf[0].tv_sec
1921#define MTIME buf[1].tv_sec
1922#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001923/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001924 struct utimbuf buf;
1925#define ATIME buf.actime
1926#define MTIME buf.modtime
1927#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001928#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001929 time_t buf[2];
1930#define ATIME buf[0]
1931#define MTIME buf[1]
1932#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001933#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001934
Barry Warsaw3cef8562000-05-01 16:17:24 +00001935 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001936 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001937 if (arg == Py_None) {
1938 /* optional time values not given */
1939 Py_BEGIN_ALLOW_THREADS
1940 res = utime(path, NULL);
1941 Py_END_ALLOW_THREADS
1942 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001943 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00001944 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001945 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001946 return NULL;
1947 }
1948 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001949 if (extract_time(PyTuple_GET_ITEM(arg, 0),
1950 &atime, &ausec) == -1)
1951 return NULL;
1952 if (extract_time(PyTuple_GET_ITEM(arg, 1),
1953 &mtime, &musec) == -1)
1954 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001955 ATIME = atime;
1956 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001957#ifdef HAVE_UTIMES
1958 buf[0].tv_usec = ausec;
1959 buf[1].tv_usec = musec;
1960 Py_BEGIN_ALLOW_THREADS
1961 res = utimes(path, buf);
1962 Py_END_ALLOW_THREADS
1963#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00001964 Py_BEGIN_ALLOW_THREADS
1965 res = utime(path, UTIME_ARG);
1966 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001967#endif
Barry Warsaw3cef8562000-05-01 16:17:24 +00001968 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001969 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001970 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001971 Py_INCREF(Py_None);
1972 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001973#undef UTIME_ARG
1974#undef ATIME
1975#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001976}
1977
Guido van Rossum85e3b011991-06-03 12:42:10 +00001978
Guido van Rossum3b066191991-06-04 19:40:25 +00001979/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001980
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001981PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001982"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001983Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001984
Barry Warsaw53699e91996-12-10 23:23:01 +00001985static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001986posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001987{
1988 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001989 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001990 return NULL;
1991 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001992 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001993}
1994
Martin v. Löwis114619e2002-10-07 06:44:21 +00001995#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
1996static void
1997free_string_array(char **array, int count)
1998{
1999 int i;
2000 for (i = 0; i < count; i++)
2001 PyMem_Free(array[i]);
2002 PyMem_DEL(array);
2003}
2004#endif
2005
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002006
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002007#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002008PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002009"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002010Execute an executable path with arguments, replacing current process.\n\
2011\n\
2012 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002013 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002014
Barry Warsaw53699e91996-12-10 23:23:01 +00002015static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002016posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002017{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002018 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002019 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002020 char **argvlist;
2021 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002022 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002023
Guido van Rossum89b33251993-10-22 14:26:06 +00002024 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002025 argv is a list or tuple of strings. */
2026
Martin v. Löwis114619e2002-10-07 06:44:21 +00002027 if (!PyArg_ParseTuple(args, "etO:execv",
2028 Py_FileSystemDefaultEncoding,
2029 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002030 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002031 if (PyList_Check(argv)) {
2032 argc = PyList_Size(argv);
2033 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002034 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002035 else if (PyTuple_Check(argv)) {
2036 argc = PyTuple_Size(argv);
2037 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002038 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002039 else {
Fred Drake661ea262000-10-24 19:57:45 +00002040 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002041 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002042 return NULL;
2043 }
2044
2045 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00002046 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002047 PyMem_Free(path);
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002048 return NULL;
2049 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002050
Barry Warsaw53699e91996-12-10 23:23:01 +00002051 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002052 if (argvlist == NULL) {
2053 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002054 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002055 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002056 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002057 if (!PyArg_Parse((*getitem)(argv, i), "et",
2058 Py_FileSystemDefaultEncoding,
2059 &argvlist[i])) {
2060 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002061 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002062 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002063 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002064 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002065
Guido van Rossum85e3b011991-06-03 12:42:10 +00002066 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002067 }
2068 argvlist[argc] = NULL;
2069
Guido van Rossumb6775db1994-08-01 11:34:53 +00002070#ifdef BAD_EXEC_PROTOTYPES
2071 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002072#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002073 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002074#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002075
Guido van Rossum85e3b011991-06-03 12:42:10 +00002076 /* If we get here it's definitely an error */
2077
Martin v. Löwis114619e2002-10-07 06:44:21 +00002078 free_string_array(argvlist, argc);
2079 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002080 return posix_error();
2081}
2082
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002083
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002084PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002085"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002086Execute a path with arguments and environment, replacing current process.\n\
2087\n\
2088 path: path of executable file\n\
2089 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002090 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002091
Barry Warsaw53699e91996-12-10 23:23:01 +00002092static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002093posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002094{
2095 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002096 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002097 char **argvlist;
2098 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002099 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002100 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002101 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002102 int lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002103
2104 /* execve has three arguments: (path, argv, env), where
2105 argv is a list or tuple of strings and env is a dictionary
2106 like posix.environ. */
2107
Martin v. Löwis114619e2002-10-07 06:44:21 +00002108 if (!PyArg_ParseTuple(args, "etOO:execve",
2109 Py_FileSystemDefaultEncoding,
2110 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002111 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002112 if (PyList_Check(argv)) {
2113 argc = PyList_Size(argv);
2114 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002115 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002116 else if (PyTuple_Check(argv)) {
2117 argc = PyTuple_Size(argv);
2118 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002119 }
2120 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002121 PyErr_SetString(PyExc_TypeError,
2122 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002123 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002124 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002125 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002126 PyErr_SetString(PyExc_TypeError,
2127 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002128 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002129 }
2130
Guido van Rossum50422b42000-04-26 20:34:28 +00002131 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00002132 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00002133 "execve() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002134 goto fail_0;
Guido van Rossum50422b42000-04-26 20:34:28 +00002135 }
2136
Barry Warsaw53699e91996-12-10 23:23:01 +00002137 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002138 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002139 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002140 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002141 }
2142 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002143 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002144 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002145 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002146 &argvlist[i]))
2147 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002148 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002149 goto fail_1;
2150 }
2151 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002152 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002153 argvlist[argc] = NULL;
2154
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002155 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002156 if (i < 0)
2157 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002158 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002159 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002160 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002161 goto fail_1;
2162 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002163 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002164 keys = PyMapping_Keys(env);
2165 vals = PyMapping_Values(env);
2166 if (!keys || !vals)
2167 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002168 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2169 PyErr_SetString(PyExc_TypeError,
2170 "execve(): env.keys() or env.values() is not a list");
2171 goto fail_2;
2172 }
Tim Peters5aa91602002-01-30 05:46:57 +00002173
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002174 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002175 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002176 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002177
2178 key = PyList_GetItem(keys, pos);
2179 val = PyList_GetItem(vals, pos);
2180 if (!key || !val)
2181 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002182
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002183 if (!PyArg_Parse(
2184 key,
2185 "s;execve() arg 3 contains a non-string key",
2186 &k) ||
2187 !PyArg_Parse(
2188 val,
2189 "s;execve() arg 3 contains a non-string value",
2190 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002191 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002192 goto fail_2;
2193 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002194
2195#if defined(PYOS_OS2)
2196 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2197 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2198#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002199 len = PyString_Size(key) + PyString_Size(val) + 2;
2200 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002201 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002202 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002203 goto fail_2;
2204 }
Tim Petersc8996f52001-12-03 20:41:00 +00002205 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002206 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002207#if defined(PYOS_OS2)
2208 }
2209#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002210 }
2211 envlist[envc] = 0;
2212
Guido van Rossumb6775db1994-08-01 11:34:53 +00002213
2214#ifdef BAD_EXEC_PROTOTYPES
2215 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002216#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002217 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002218#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00002219
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002220 /* If we get here it's definitely an error */
2221
2222 (void) posix_error();
2223
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002224 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002225 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002226 PyMem_DEL(envlist[envc]);
2227 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002228 fail_1:
2229 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002230 Py_XDECREF(vals);
2231 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002232 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002233 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002234 return NULL;
2235}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002236#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002237
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002238
Guido van Rossuma1065681999-01-25 23:20:23 +00002239#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002240PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002241"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002242Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002243\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002244 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002245 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002246 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002247
2248static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002249posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002250{
2251 char *path;
2252 PyObject *argv;
2253 char **argvlist;
2254 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002255 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002256 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00002257
2258 /* spawnv has three arguments: (mode, path, argv), where
2259 argv is a list or tuple of strings. */
2260
Martin v. Löwis114619e2002-10-07 06:44:21 +00002261 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2262 Py_FileSystemDefaultEncoding,
2263 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002264 return NULL;
2265 if (PyList_Check(argv)) {
2266 argc = PyList_Size(argv);
2267 getitem = PyList_GetItem;
2268 }
2269 else if (PyTuple_Check(argv)) {
2270 argc = PyTuple_Size(argv);
2271 getitem = PyTuple_GetItem;
2272 }
2273 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002274 PyErr_SetString(PyExc_TypeError,
2275 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002276 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002277 return NULL;
2278 }
2279
2280 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002281 if (argvlist == NULL) {
2282 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002283 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002284 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002285 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002286 if (!PyArg_Parse((*getitem)(argv, i), "et",
2287 Py_FileSystemDefaultEncoding,
2288 &argvlist[i])) {
2289 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002290 PyErr_SetString(
2291 PyExc_TypeError,
2292 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002293 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002294 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002295 }
2296 }
2297 argvlist[argc] = NULL;
2298
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002299#if defined(PYOS_OS2) && defined(PYCC_GCC)
2300 Py_BEGIN_ALLOW_THREADS
2301 spawnval = spawnv(mode, path, argvlist);
2302 Py_END_ALLOW_THREADS
2303#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002304 if (mode == _OLD_P_OVERLAY)
2305 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002306
Tim Peters25059d32001-12-07 20:35:43 +00002307 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002308 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002309 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002310#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002311
Martin v. Löwis114619e2002-10-07 06:44:21 +00002312 free_string_array(argvlist, argc);
2313 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002314
Fred Drake699f3522000-06-29 21:12:41 +00002315 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002316 return posix_error();
2317 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002318#if SIZEOF_LONG == SIZEOF_VOID_P
2319 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002320#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002321 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002322#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002323}
2324
2325
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002326PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002327"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002328Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002329\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002330 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002331 path: path of executable file\n\
2332 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002333 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002334
2335static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002336posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002337{
2338 char *path;
2339 PyObject *argv, *env;
2340 char **argvlist;
2341 char **envlist;
2342 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2343 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002344 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002345 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002346 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002347
2348 /* spawnve has four arguments: (mode, path, argv, env), where
2349 argv is a list or tuple of strings and env is a dictionary
2350 like posix.environ. */
2351
Martin v. Löwis114619e2002-10-07 06:44:21 +00002352 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2353 Py_FileSystemDefaultEncoding,
2354 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002355 return NULL;
2356 if (PyList_Check(argv)) {
2357 argc = PyList_Size(argv);
2358 getitem = PyList_GetItem;
2359 }
2360 else if (PyTuple_Check(argv)) {
2361 argc = PyTuple_Size(argv);
2362 getitem = PyTuple_GetItem;
2363 }
2364 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002365 PyErr_SetString(PyExc_TypeError,
2366 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002367 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002368 }
2369 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002370 PyErr_SetString(PyExc_TypeError,
2371 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002372 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002373 }
2374
2375 argvlist = PyMem_NEW(char *, argc+1);
2376 if (argvlist == NULL) {
2377 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002378 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002379 }
2380 for (i = 0; i < argc; i++) {
2381 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002382 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002383 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002384 &argvlist[i]))
2385 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002386 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002387 goto fail_1;
2388 }
2389 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002390 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002391 argvlist[argc] = NULL;
2392
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002393 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002394 if (i < 0)
2395 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002396 envlist = PyMem_NEW(char *, i + 1);
2397 if (envlist == NULL) {
2398 PyErr_NoMemory();
2399 goto fail_1;
2400 }
2401 envc = 0;
2402 keys = PyMapping_Keys(env);
2403 vals = PyMapping_Values(env);
2404 if (!keys || !vals)
2405 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002406 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2407 PyErr_SetString(PyExc_TypeError,
2408 "spawnve(): env.keys() or env.values() is not a list");
2409 goto fail_2;
2410 }
Tim Peters5aa91602002-01-30 05:46:57 +00002411
Guido van Rossuma1065681999-01-25 23:20:23 +00002412 for (pos = 0; pos < i; pos++) {
2413 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002414 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002415
2416 key = PyList_GetItem(keys, pos);
2417 val = PyList_GetItem(vals, pos);
2418 if (!key || !val)
2419 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002420
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002421 if (!PyArg_Parse(
2422 key,
2423 "s;spawnve() arg 3 contains a non-string key",
2424 &k) ||
2425 !PyArg_Parse(
2426 val,
2427 "s;spawnve() arg 3 contains a non-string value",
2428 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002429 {
2430 goto fail_2;
2431 }
Tim Petersc8996f52001-12-03 20:41:00 +00002432 len = PyString_Size(key) + PyString_Size(val) + 2;
2433 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002434 if (p == NULL) {
2435 PyErr_NoMemory();
2436 goto fail_2;
2437 }
Tim Petersc8996f52001-12-03 20:41:00 +00002438 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002439 envlist[envc++] = p;
2440 }
2441 envlist[envc] = 0;
2442
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002443#if defined(PYOS_OS2) && defined(PYCC_GCC)
2444 Py_BEGIN_ALLOW_THREADS
2445 spawnval = spawnve(mode, path, argvlist, envlist);
2446 Py_END_ALLOW_THREADS
2447#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002448 if (mode == _OLD_P_OVERLAY)
2449 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002450
2451 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002452 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002453 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002454#endif
Tim Peters25059d32001-12-07 20:35:43 +00002455
Fred Drake699f3522000-06-29 21:12:41 +00002456 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002457 (void) posix_error();
2458 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002459#if SIZEOF_LONG == SIZEOF_VOID_P
2460 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002461#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002462 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002463#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002464
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002465 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00002466 while (--envc >= 0)
2467 PyMem_DEL(envlist[envc]);
2468 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002469 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002470 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002471 Py_XDECREF(vals);
2472 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002473 fail_0:
2474 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002475 return res;
2476}
2477#endif /* HAVE_SPAWNV */
2478
2479
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002480#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002481PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002482"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002483Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
2484\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002485Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002486
2487static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002488posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002489{
Neal Norwitze241ce82003-02-17 18:17:05 +00002490 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002491 if (pid == -1)
2492 return posix_error();
2493 PyOS_AfterFork();
2494 return PyInt_FromLong((long)pid);
2495}
2496#endif
2497
2498
Guido van Rossumad0ee831995-03-01 10:34:45 +00002499#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002500PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002501"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002502Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002503Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002504
Barry Warsaw53699e91996-12-10 23:23:01 +00002505static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002506posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002507{
Neal Norwitze241ce82003-02-17 18:17:05 +00002508 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00002509 if (pid == -1)
2510 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002511 if (pid == 0)
2512 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00002513 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002514}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002515#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002516
Neal Norwitzb59798b2003-03-21 01:43:31 +00002517/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00002518/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
2519#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00002520#define DEV_PTY_FILE "/dev/ptc"
2521#define HAVE_DEV_PTMX
2522#else
2523#define DEV_PTY_FILE "/dev/ptmx"
2524#endif
2525
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002526#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002527#ifdef HAVE_PTY_H
2528#include <pty.h>
2529#else
2530#ifdef HAVE_LIBUTIL_H
2531#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00002532#endif /* HAVE_LIBUTIL_H */
2533#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00002534#ifdef HAVE_STROPTS_H
2535#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002536#endif
2537#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002538
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002539#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002540PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002541"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002542Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002543
2544static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002545posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002546{
2547 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002548#ifndef HAVE_OPENPTY
2549 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002550#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002551#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002552 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002553#ifdef sun
2554 extern char *ptsname();
2555#endif
2556#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00002557
Thomas Wouters70c21a12000-07-14 14:28:33 +00002558#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00002559 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2560 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00002561#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00002562 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2563 if (slave_name == NULL)
2564 return posix_error();
2565
2566 slave_fd = open(slave_name, O_RDWR);
2567 if (slave_fd < 0)
2568 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002569#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00002570 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002571 if (master_fd < 0)
2572 return posix_error();
2573 sig_saved = signal(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002574 /* change permission of slave */
2575 if (grantpt(master_fd) < 0) {
2576 signal(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002577 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002578 }
2579 /* unlock slave */
2580 if (unlockpt(master_fd) < 0) {
2581 signal(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002582 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002583 }
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002584 signal(SIGCHLD, sig_saved);
2585 slave_name = ptsname(master_fd); /* get name of slave */
2586 if (slave_name == NULL)
2587 return posix_error();
2588 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
2589 if (slave_fd < 0)
2590 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00002591#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002592 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
2593 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00002594#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002595 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00002596#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002597#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00002598#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002599
Fred Drake8cef4cf2000-06-28 16:40:38 +00002600 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00002601
Fred Drake8cef4cf2000-06-28 16:40:38 +00002602}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002603#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002604
2605#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002606PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002607"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00002608Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2609Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002610To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002611
2612static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002613posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002614{
2615 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002616
Fred Drake8cef4cf2000-06-28 16:40:38 +00002617 pid = forkpty(&master_fd, NULL, NULL, NULL);
2618 if (pid == -1)
2619 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002620 if (pid == 0)
2621 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002622 return Py_BuildValue("(ii)", pid, master_fd);
2623}
2624#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002625
Guido van Rossumad0ee831995-03-01 10:34:45 +00002626#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002627PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002628"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002629Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002630
Barry Warsaw53699e91996-12-10 23:23:01 +00002631static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002632posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002633{
Barry Warsaw53699e91996-12-10 23:23:01 +00002634 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002635}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002636#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002637
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002638
Guido van Rossumad0ee831995-03-01 10:34:45 +00002639#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002640PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002641"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002642Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002643
Barry Warsaw53699e91996-12-10 23:23:01 +00002644static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002645posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002646{
Barry Warsaw53699e91996-12-10 23:23:01 +00002647 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002648}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002649#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002650
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002651
Guido van Rossumad0ee831995-03-01 10:34:45 +00002652#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002653PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002654"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002655Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002656
Barry Warsaw53699e91996-12-10 23:23:01 +00002657static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002658posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002659{
Barry Warsaw53699e91996-12-10 23:23:01 +00002660 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002661}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002662#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002663
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002664
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002665PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002666"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002667Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002668
Barry Warsaw53699e91996-12-10 23:23:01 +00002669static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002670posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002671{
Barry Warsaw53699e91996-12-10 23:23:01 +00002672 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002673}
2674
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002675
Fred Drakec9680921999-12-13 16:37:25 +00002676#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002677PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002678"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002679Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00002680
2681static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002682posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00002683{
2684 PyObject *result = NULL;
2685
Fred Drakec9680921999-12-13 16:37:25 +00002686#ifdef NGROUPS_MAX
2687#define MAX_GROUPS NGROUPS_MAX
2688#else
2689 /* defined to be 16 on Solaris7, so this should be a small number */
2690#define MAX_GROUPS 64
2691#endif
2692 gid_t grouplist[MAX_GROUPS];
2693 int n;
2694
2695 n = getgroups(MAX_GROUPS, grouplist);
2696 if (n < 0)
2697 posix_error();
2698 else {
2699 result = PyList_New(n);
2700 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00002701 int i;
2702 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00002703 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00002704 if (o == NULL) {
2705 Py_DECREF(result);
2706 result = NULL;
2707 break;
2708 }
2709 PyList_SET_ITEM(result, i, o);
2710 }
2711 }
2712 }
Neal Norwitze241ce82003-02-17 18:17:05 +00002713
Fred Drakec9680921999-12-13 16:37:25 +00002714 return result;
2715}
2716#endif
2717
Martin v. Löwis606edc12002-06-13 21:09:11 +00002718#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002719PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002720"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002721Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00002722
2723static PyObject *
2724posix_getpgid(PyObject *self, PyObject *args)
2725{
2726 int pid, pgid;
2727 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
2728 return NULL;
2729 pgid = getpgid(pid);
2730 if (pgid < 0)
2731 return posix_error();
2732 return PyInt_FromLong((long)pgid);
2733}
2734#endif /* HAVE_GETPGID */
2735
2736
Guido van Rossumb6775db1994-08-01 11:34:53 +00002737#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002738PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002739"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002740Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002741
Barry Warsaw53699e91996-12-10 23:23:01 +00002742static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002743posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00002744{
Guido van Rossumb6775db1994-08-01 11:34:53 +00002745#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002746 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002747#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002748 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002749#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002750}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002751#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002752
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002753
Guido van Rossumb6775db1994-08-01 11:34:53 +00002754#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002755PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002756"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002757Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002758
Barry Warsaw53699e91996-12-10 23:23:01 +00002759static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002760posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002761{
Guido van Rossum64933891994-10-20 21:56:42 +00002762#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002763 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002764#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002765 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002766#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002767 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002768 Py_INCREF(Py_None);
2769 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002770}
2771
Guido van Rossumb6775db1994-08-01 11:34:53 +00002772#endif /* HAVE_SETPGRP */
2773
Guido van Rossumad0ee831995-03-01 10:34:45 +00002774#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002775PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002776"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002777Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002778
Barry Warsaw53699e91996-12-10 23:23:01 +00002779static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002780posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002781{
Barry Warsaw53699e91996-12-10 23:23:01 +00002782 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002783}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002784#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002785
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002786
Fred Drake12c6e2d1999-12-14 21:25:03 +00002787#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002788PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002789"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002790Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00002791
2792static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002793posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002794{
Neal Norwitze241ce82003-02-17 18:17:05 +00002795 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00002796 char *name;
2797 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002798
Fred Drakea30680b2000-12-06 21:24:28 +00002799 errno = 0;
2800 name = getlogin();
2801 if (name == NULL) {
2802 if (errno)
2803 posix_error();
2804 else
2805 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002806 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002807 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002808 else
2809 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002810 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00002811
Fred Drake12c6e2d1999-12-14 21:25:03 +00002812 return result;
2813}
2814#endif
2815
Guido van Rossumad0ee831995-03-01 10:34:45 +00002816#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002817PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002818"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002819Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002820
Barry Warsaw53699e91996-12-10 23:23:01 +00002821static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002822posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002823{
Barry Warsaw53699e91996-12-10 23:23:01 +00002824 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002825}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002826#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002827
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002828
Guido van Rossumad0ee831995-03-01 10:34:45 +00002829#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002830PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002831"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002832Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002833
Barry Warsaw53699e91996-12-10 23:23:01 +00002834static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002835posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002836{
2837 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002838 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002839 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002840#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002841 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2842 APIRET rc;
2843 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002844 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002845
2846 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2847 APIRET rc;
2848 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002849 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002850
2851 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002852 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002853#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002854 if (kill(pid, sig) == -1)
2855 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002856#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002857 Py_INCREF(Py_None);
2858 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002859}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002860#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002861
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002862#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002863PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002864"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002865Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002866
2867static PyObject *
2868posix_killpg(PyObject *self, PyObject *args)
2869{
2870 int pgid, sig;
2871 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
2872 return NULL;
2873 if (killpg(pgid, sig) == -1)
2874 return posix_error();
2875 Py_INCREF(Py_None);
2876 return Py_None;
2877}
2878#endif
2879
Guido van Rossumc0125471996-06-28 18:55:32 +00002880#ifdef HAVE_PLOCK
2881
2882#ifdef HAVE_SYS_LOCK_H
2883#include <sys/lock.h>
2884#endif
2885
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002886PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002887"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002888Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002889
Barry Warsaw53699e91996-12-10 23:23:01 +00002890static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002891posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002892{
2893 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002894 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002895 return NULL;
2896 if (plock(op) == -1)
2897 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002898 Py_INCREF(Py_None);
2899 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002900}
2901#endif
2902
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002903
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002904#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002905PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002906"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002907Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002908
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002909#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002910#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002911static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002912async_system(const char *command)
2913{
2914 char *p, errormsg[256], args[1024];
2915 RESULTCODES rcodes;
2916 APIRET rc;
2917 char *shell = getenv("COMSPEC");
2918 if (!shell)
2919 shell = "cmd";
2920
2921 strcpy(args, shell);
2922 p = &args[ strlen(args)+1 ];
2923 strcpy(p, "/c ");
2924 strcat(p, command);
2925 p += strlen(p) + 1;
2926 *p = '\0';
2927
2928 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002929 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002930 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002931 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002932 &rcodes, shell);
2933 return rc;
2934}
2935
Guido van Rossumd48f2521997-12-05 22:19:34 +00002936static FILE *
2937popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002938{
2939 HFILE rhan, whan;
2940 FILE *retfd = NULL;
2941 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2942
Guido van Rossumd48f2521997-12-05 22:19:34 +00002943 if (rc != NO_ERROR) {
2944 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002945 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002946 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002947
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002948 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2949 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002950
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002951 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2952 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002953
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002954 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2955 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002956
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002957 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002958 }
2959
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002960 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2961 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002962
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002963 if (rc == NO_ERROR)
2964 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2965
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002966 close(oldfd); /* And Close Saved STDOUT Handle */
2967 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002968
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002969 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2970 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002971
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002972 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2973 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002974
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002975 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2976 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002977
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002978 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002979 }
2980
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002981 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2982 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002983
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002984 if (rc == NO_ERROR)
2985 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2986
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002987 close(oldfd); /* And Close Saved STDIN Handle */
2988 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002989
Guido van Rossumd48f2521997-12-05 22:19:34 +00002990 } else {
2991 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002992 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002993 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002994}
2995
2996static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002997posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002998{
2999 char *name;
3000 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003001 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003002 FILE *fp;
3003 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003004 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003005 return NULL;
3006 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003007 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003008 Py_END_ALLOW_THREADS
3009 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003010 return os2_error(err);
3011
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003012 f = PyFile_FromFile(fp, name, mode, fclose);
3013 if (f != NULL)
3014 PyFile_SetBufSize(f, bufsize);
3015 return f;
3016}
3017
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003018#elif defined(PYCC_GCC)
3019
3020/* standard posix version of popen() support */
3021static PyObject *
3022posix_popen(PyObject *self, PyObject *args)
3023{
3024 char *name;
3025 char *mode = "r";
3026 int bufsize = -1;
3027 FILE *fp;
3028 PyObject *f;
3029 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3030 return NULL;
3031 Py_BEGIN_ALLOW_THREADS
3032 fp = popen(name, mode);
3033 Py_END_ALLOW_THREADS
3034 if (fp == NULL)
3035 return posix_error();
3036 f = PyFile_FromFile(fp, name, mode, pclose);
3037 if (f != NULL)
3038 PyFile_SetBufSize(f, bufsize);
3039 return f;
3040}
3041
3042/* fork() under OS/2 has lots'o'warts
3043 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3044 * most of this code is a ripoff of the win32 code, but using the
3045 * capabilities of EMX's C library routines
3046 */
3047
3048/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3049#define POPEN_1 1
3050#define POPEN_2 2
3051#define POPEN_3 3
3052#define POPEN_4 4
3053
3054static PyObject *_PyPopen(char *, int, int, int);
3055static int _PyPclose(FILE *file);
3056
3057/*
3058 * Internal dictionary mapping popen* file pointers to process handles,
3059 * for use when retrieving the process exit code. See _PyPclose() below
3060 * for more information on this dictionary's use.
3061 */
3062static PyObject *_PyPopenProcs = NULL;
3063
3064/* os2emx version of popen2()
3065 *
3066 * The result of this function is a pipe (file) connected to the
3067 * process's stdin, and a pipe connected to the process's stdout.
3068 */
3069
3070static PyObject *
3071os2emx_popen2(PyObject *self, PyObject *args)
3072{
3073 PyObject *f;
3074 int tm=0;
3075
3076 char *cmdstring;
3077 char *mode = "t";
3078 int bufsize = -1;
3079 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3080 return NULL;
3081
3082 if (*mode == 't')
3083 tm = O_TEXT;
3084 else if (*mode != 'b') {
3085 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3086 return NULL;
3087 } else
3088 tm = O_BINARY;
3089
3090 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3091
3092 return f;
3093}
3094
3095/*
3096 * Variation on os2emx.popen2
3097 *
3098 * The result of this function is 3 pipes - the process's stdin,
3099 * stdout and stderr
3100 */
3101
3102static PyObject *
3103os2emx_popen3(PyObject *self, PyObject *args)
3104{
3105 PyObject *f;
3106 int tm = 0;
3107
3108 char *cmdstring;
3109 char *mode = "t";
3110 int bufsize = -1;
3111 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3112 return NULL;
3113
3114 if (*mode == 't')
3115 tm = O_TEXT;
3116 else if (*mode != 'b') {
3117 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3118 return NULL;
3119 } else
3120 tm = O_BINARY;
3121
3122 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3123
3124 return f;
3125}
3126
3127/*
3128 * Variation on os2emx.popen2
3129 *
Tim Peters11b23062003-04-23 02:39:17 +00003130 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003131 * and stdout+stderr combined as a single pipe.
3132 */
3133
3134static PyObject *
3135os2emx_popen4(PyObject *self, PyObject *args)
3136{
3137 PyObject *f;
3138 int tm = 0;
3139
3140 char *cmdstring;
3141 char *mode = "t";
3142 int bufsize = -1;
3143 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3144 return NULL;
3145
3146 if (*mode == 't')
3147 tm = O_TEXT;
3148 else if (*mode != 'b') {
3149 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3150 return NULL;
3151 } else
3152 tm = O_BINARY;
3153
3154 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3155
3156 return f;
3157}
3158
3159/* a couple of structures for convenient handling of multiple
3160 * file handles and pipes
3161 */
3162struct file_ref
3163{
3164 int handle;
3165 int flags;
3166};
3167
3168struct pipe_ref
3169{
3170 int rd;
3171 int wr;
3172};
3173
3174/* The following code is derived from the win32 code */
3175
3176static PyObject *
3177_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3178{
3179 struct file_ref stdio[3];
3180 struct pipe_ref p_fd[3];
3181 FILE *p_s[3];
3182 int file_count, i, pipe_err, pipe_pid;
3183 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3184 PyObject *f, *p_f[3];
3185
3186 /* file modes for subsequent fdopen's on pipe handles */
3187 if (mode == O_TEXT)
3188 {
3189 rd_mode = "rt";
3190 wr_mode = "wt";
3191 }
3192 else
3193 {
3194 rd_mode = "rb";
3195 wr_mode = "wb";
3196 }
3197
3198 /* prepare shell references */
3199 if ((shell = getenv("EMXSHELL")) == NULL)
3200 if ((shell = getenv("COMSPEC")) == NULL)
3201 {
3202 errno = ENOENT;
3203 return posix_error();
3204 }
3205
3206 sh_name = _getname(shell);
3207 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3208 opt = "/c";
3209 else
3210 opt = "-c";
3211
3212 /* save current stdio fds + their flags, and set not inheritable */
3213 i = pipe_err = 0;
3214 while (pipe_err >= 0 && i < 3)
3215 {
3216 pipe_err = stdio[i].handle = dup(i);
3217 stdio[i].flags = fcntl(i, F_GETFD, 0);
3218 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3219 i++;
3220 }
3221 if (pipe_err < 0)
3222 {
3223 /* didn't get them all saved - clean up and bail out */
3224 int saved_err = errno;
3225 while (i-- > 0)
3226 {
3227 close(stdio[i].handle);
3228 }
3229 errno = saved_err;
3230 return posix_error();
3231 }
3232
3233 /* create pipe ends */
3234 file_count = 2;
3235 if (n == POPEN_3)
3236 file_count = 3;
3237 i = pipe_err = 0;
3238 while ((pipe_err == 0) && (i < file_count))
3239 pipe_err = pipe((int *)&p_fd[i++]);
3240 if (pipe_err < 0)
3241 {
3242 /* didn't get them all made - clean up and bail out */
3243 while (i-- > 0)
3244 {
3245 close(p_fd[i].wr);
3246 close(p_fd[i].rd);
3247 }
3248 errno = EPIPE;
3249 return posix_error();
3250 }
3251
3252 /* change the actual standard IO streams over temporarily,
3253 * making the retained pipe ends non-inheritable
3254 */
3255 pipe_err = 0;
3256
3257 /* - stdin */
3258 if (dup2(p_fd[0].rd, 0) == 0)
3259 {
3260 close(p_fd[0].rd);
3261 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3262 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3263 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3264 {
3265 close(p_fd[0].wr);
3266 pipe_err = -1;
3267 }
3268 }
3269 else
3270 {
3271 pipe_err = -1;
3272 }
3273
3274 /* - stdout */
3275 if (pipe_err == 0)
3276 {
3277 if (dup2(p_fd[1].wr, 1) == 1)
3278 {
3279 close(p_fd[1].wr);
3280 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3281 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3282 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3283 {
3284 close(p_fd[1].rd);
3285 pipe_err = -1;
3286 }
3287 }
3288 else
3289 {
3290 pipe_err = -1;
3291 }
3292 }
3293
3294 /* - stderr, as required */
3295 if (pipe_err == 0)
3296 switch (n)
3297 {
3298 case POPEN_3:
3299 {
3300 if (dup2(p_fd[2].wr, 2) == 2)
3301 {
3302 close(p_fd[2].wr);
3303 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3304 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3305 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3306 {
3307 close(p_fd[2].rd);
3308 pipe_err = -1;
3309 }
3310 }
3311 else
3312 {
3313 pipe_err = -1;
3314 }
3315 break;
3316 }
3317
3318 case POPEN_4:
3319 {
3320 if (dup2(1, 2) != 2)
3321 {
3322 pipe_err = -1;
3323 }
3324 break;
3325 }
3326 }
3327
3328 /* spawn the child process */
3329 if (pipe_err == 0)
3330 {
3331 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3332 if (pipe_pid == -1)
3333 {
3334 pipe_err = -1;
3335 }
3336 else
3337 {
3338 /* save the PID into the FILE structure
3339 * NOTE: this implementation doesn't actually
3340 * take advantage of this, but do it for
3341 * completeness - AIM Apr01
3342 */
3343 for (i = 0; i < file_count; i++)
3344 p_s[i]->_pid = pipe_pid;
3345 }
3346 }
3347
3348 /* reset standard IO to normal */
3349 for (i = 0; i < 3; i++)
3350 {
3351 dup2(stdio[i].handle, i);
3352 fcntl(i, F_SETFD, stdio[i].flags);
3353 close(stdio[i].handle);
3354 }
3355
3356 /* if any remnant problems, clean up and bail out */
3357 if (pipe_err < 0)
3358 {
3359 for (i = 0; i < 3; i++)
3360 {
3361 close(p_fd[i].rd);
3362 close(p_fd[i].wr);
3363 }
3364 errno = EPIPE;
3365 return posix_error_with_filename(cmdstring);
3366 }
3367
3368 /* build tuple of file objects to return */
3369 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3370 PyFile_SetBufSize(p_f[0], bufsize);
3371 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3372 PyFile_SetBufSize(p_f[1], bufsize);
3373 if (n == POPEN_3)
3374 {
3375 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3376 PyFile_SetBufSize(p_f[0], bufsize);
3377 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
3378 }
3379 else
3380 f = Py_BuildValue("OO", p_f[0], p_f[1]);
3381
3382 /*
3383 * Insert the files we've created into the process dictionary
3384 * all referencing the list with the process handle and the
3385 * initial number of files (see description below in _PyPclose).
3386 * Since if _PyPclose later tried to wait on a process when all
3387 * handles weren't closed, it could create a deadlock with the
3388 * child, we spend some energy here to try to ensure that we
3389 * either insert all file handles into the dictionary or none
3390 * at all. It's a little clumsy with the various popen modes
3391 * and variable number of files involved.
3392 */
3393 if (!_PyPopenProcs)
3394 {
3395 _PyPopenProcs = PyDict_New();
3396 }
3397
3398 if (_PyPopenProcs)
3399 {
3400 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3401 int ins_rc[3];
3402
3403 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3404 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3405
3406 procObj = PyList_New(2);
3407 pidObj = PyInt_FromLong((long) pipe_pid);
3408 intObj = PyInt_FromLong((long) file_count);
3409
3410 if (procObj && pidObj && intObj)
3411 {
3412 PyList_SetItem(procObj, 0, pidObj);
3413 PyList_SetItem(procObj, 1, intObj);
3414
3415 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3416 if (fileObj[0])
3417 {
3418 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3419 fileObj[0],
3420 procObj);
3421 }
3422 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3423 if (fileObj[1])
3424 {
3425 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3426 fileObj[1],
3427 procObj);
3428 }
3429 if (file_count >= 3)
3430 {
3431 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3432 if (fileObj[2])
3433 {
3434 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3435 fileObj[2],
3436 procObj);
3437 }
3438 }
3439
3440 if (ins_rc[0] < 0 || !fileObj[0] ||
3441 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3442 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3443 {
3444 /* Something failed - remove any dictionary
3445 * entries that did make it.
3446 */
3447 if (!ins_rc[0] && fileObj[0])
3448 {
3449 PyDict_DelItem(_PyPopenProcs,
3450 fileObj[0]);
3451 }
3452 if (!ins_rc[1] && fileObj[1])
3453 {
3454 PyDict_DelItem(_PyPopenProcs,
3455 fileObj[1]);
3456 }
3457 if (!ins_rc[2] && fileObj[2])
3458 {
3459 PyDict_DelItem(_PyPopenProcs,
3460 fileObj[2]);
3461 }
3462 }
3463 }
Tim Peters11b23062003-04-23 02:39:17 +00003464
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003465 /*
3466 * Clean up our localized references for the dictionary keys
3467 * and value since PyDict_SetItem will Py_INCREF any copies
3468 * that got placed in the dictionary.
3469 */
3470 Py_XDECREF(procObj);
3471 Py_XDECREF(fileObj[0]);
3472 Py_XDECREF(fileObj[1]);
3473 Py_XDECREF(fileObj[2]);
3474 }
3475
3476 /* Child is launched. */
3477 return f;
3478}
3479
3480/*
3481 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3482 * exit code for the child process and return as a result of the close.
3483 *
3484 * This function uses the _PyPopenProcs dictionary in order to map the
3485 * input file pointer to information about the process that was
3486 * originally created by the popen* call that created the file pointer.
3487 * The dictionary uses the file pointer as a key (with one entry
3488 * inserted for each file returned by the original popen* call) and a
3489 * single list object as the value for all files from a single call.
3490 * The list object contains the Win32 process handle at [0], and a file
3491 * count at [1], which is initialized to the total number of file
3492 * handles using that list.
3493 *
3494 * This function closes whichever handle it is passed, and decrements
3495 * the file count in the dictionary for the process handle pointed to
3496 * by this file. On the last close (when the file count reaches zero),
3497 * this function will wait for the child process and then return its
3498 * exit code as the result of the close() operation. This permits the
3499 * files to be closed in any order - it is always the close() of the
3500 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003501 *
3502 * NOTE: This function is currently called with the GIL released.
3503 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003504 */
3505
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003506static int _PyPclose(FILE *file)
3507{
3508 int result;
3509 int exit_code;
3510 int pipe_pid;
3511 PyObject *procObj, *pidObj, *intObj, *fileObj;
3512 int file_count;
3513#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003514 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003515#endif
3516
3517 /* Close the file handle first, to ensure it can't block the
3518 * child from exiting if it's the last handle.
3519 */
3520 result = fclose(file);
3521
3522#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003523 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003524#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003525 if (_PyPopenProcs)
3526 {
3527 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3528 (procObj = PyDict_GetItem(_PyPopenProcs,
3529 fileObj)) != NULL &&
3530 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
3531 (intObj = PyList_GetItem(procObj,1)) != NULL)
3532 {
3533 pipe_pid = (int) PyInt_AsLong(pidObj);
3534 file_count = (int) PyInt_AsLong(intObj);
3535
3536 if (file_count > 1)
3537 {
3538 /* Still other files referencing process */
3539 file_count--;
3540 PyList_SetItem(procObj,1,
3541 PyInt_FromLong((long) file_count));
3542 }
3543 else
3544 {
3545 /* Last file for this process */
3546 if (result != EOF &&
3547 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
3548 {
3549 /* extract exit status */
3550 if (WIFEXITED(exit_code))
3551 {
3552 result = WEXITSTATUS(exit_code);
3553 }
3554 else
3555 {
3556 errno = EPIPE;
3557 result = -1;
3558 }
3559 }
3560 else
3561 {
3562 /* Indicate failure - this will cause the file object
3563 * to raise an I/O error and translate the last
3564 * error code from errno. We do have a problem with
3565 * last errors that overlap the normal errno table,
3566 * but that's a consistent problem with the file object.
3567 */
3568 result = -1;
3569 }
3570 }
3571
3572 /* Remove this file pointer from dictionary */
3573 PyDict_DelItem(_PyPopenProcs, fileObj);
3574
3575 if (PyDict_Size(_PyPopenProcs) == 0)
3576 {
3577 Py_DECREF(_PyPopenProcs);
3578 _PyPopenProcs = NULL;
3579 }
3580
3581 } /* if object retrieval ok */
3582
3583 Py_XDECREF(fileObj);
3584 } /* if _PyPopenProcs */
3585
3586#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003587 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003588#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003589 return result;
3590}
3591
3592#endif /* PYCC_??? */
3593
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003594#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003595
3596/*
3597 * Portable 'popen' replacement for Win32.
3598 *
3599 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3600 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003601 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003602 */
3603
3604#include <malloc.h>
3605#include <io.h>
3606#include <fcntl.h>
3607
3608/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3609#define POPEN_1 1
3610#define POPEN_2 2
3611#define POPEN_3 3
3612#define POPEN_4 4
3613
3614static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003615static int _PyPclose(FILE *file);
3616
3617/*
3618 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003619 * for use when retrieving the process exit code. See _PyPclose() below
3620 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003621 */
3622static PyObject *_PyPopenProcs = NULL;
3623
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003624
3625/* popen that works from a GUI.
3626 *
3627 * The result of this function is a pipe (file) connected to the
3628 * processes stdin or stdout, depending on the requested mode.
3629 */
3630
3631static PyObject *
3632posix_popen(PyObject *self, PyObject *args)
3633{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00003634 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003635 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003636
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003637 char *cmdstring;
3638 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003639 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003640 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003641 return NULL;
3642
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003643 if (*mode == 'r')
3644 tm = _O_RDONLY;
3645 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003646 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003647 return NULL;
3648 } else
3649 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003650
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003651 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003652 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003653 return NULL;
3654 }
3655
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003656 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003657 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003658 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003659 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003660 else
3661 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3662
3663 return f;
3664}
3665
3666/* Variation on win32pipe.popen
3667 *
3668 * The result of this function is a pipe (file) connected to the
3669 * process's stdin, and a pipe connected to the process's stdout.
3670 */
3671
3672static PyObject *
3673win32_popen2(PyObject *self, PyObject *args)
3674{
3675 PyObject *f;
3676 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003677
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003678 char *cmdstring;
3679 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003680 int bufsize = -1;
3681 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003682 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003683
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003684 if (*mode == 't')
3685 tm = _O_TEXT;
3686 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003687 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003688 return NULL;
3689 } else
3690 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003691
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003692 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003693 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003694 return NULL;
3695 }
3696
3697 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003698
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003699 return f;
3700}
3701
3702/*
3703 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003704 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003705 * The result of this function is 3 pipes - the process's stdin,
3706 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003707 */
3708
3709static PyObject *
3710win32_popen3(PyObject *self, PyObject *args)
3711{
3712 PyObject *f;
3713 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003714
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003715 char *cmdstring;
3716 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003717 int bufsize = -1;
3718 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003719 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003720
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003721 if (*mode == 't')
3722 tm = _O_TEXT;
3723 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003724 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003725 return NULL;
3726 } else
3727 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003728
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003729 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003730 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003731 return NULL;
3732 }
3733
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003734 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003735
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003736 return f;
3737}
3738
3739/*
3740 * Variation on win32pipe.popen
3741 *
Tim Peters5aa91602002-01-30 05:46:57 +00003742 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003743 * and stdout+stderr combined as a single pipe.
3744 */
3745
3746static PyObject *
3747win32_popen4(PyObject *self, PyObject *args)
3748{
3749 PyObject *f;
3750 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003751
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003752 char *cmdstring;
3753 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003754 int bufsize = -1;
3755 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003756 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003757
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003758 if (*mode == 't')
3759 tm = _O_TEXT;
3760 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003761 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003762 return NULL;
3763 } else
3764 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003765
3766 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003767 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003768 return NULL;
3769 }
3770
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003771 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003772
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003773 return f;
3774}
3775
Mark Hammond08501372001-01-31 07:30:29 +00003776static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003777_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003778 HANDLE hStdin,
3779 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003780 HANDLE hStderr,
3781 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003782{
3783 PROCESS_INFORMATION piProcInfo;
3784 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003785 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003786 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003787 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003788 int i;
3789 int x;
3790
3791 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003792 char *comshell;
3793
Tim Peters92e4dd82002-10-05 01:47:34 +00003794 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003795 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3796 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003797
3798 /* Explicitly check if we are using COMMAND.COM. If we are
3799 * then use the w9xpopen hack.
3800 */
3801 comshell = s1 + x;
3802 while (comshell >= s1 && *comshell != '\\')
3803 --comshell;
3804 ++comshell;
3805
3806 if (GetVersion() < 0x80000000 &&
3807 _stricmp(comshell, "command.com") != 0) {
3808 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003809 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00003810 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003811 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003812 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003813 }
3814 else {
3815 /*
Tim Peters402d5982001-08-27 06:37:48 +00003816 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3817 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003818 */
Mark Hammond08501372001-01-31 07:30:29 +00003819 char modulepath[_MAX_PATH];
3820 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003821 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3822 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003823 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003824 x = i+1;
3825 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00003826 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00003827 strncat(modulepath,
3828 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003829 (sizeof(modulepath)/sizeof(modulepath[0]))
3830 -strlen(modulepath));
3831 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003832 /* Eeek - file-not-found - possibly an embedding
3833 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00003834 */
Tim Peters5aa91602002-01-30 05:46:57 +00003835 strncpy(modulepath,
3836 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00003837 sizeof(modulepath)/sizeof(modulepath[0]));
3838 if (modulepath[strlen(modulepath)-1] != '\\')
3839 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00003840 strncat(modulepath,
3841 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003842 (sizeof(modulepath)/sizeof(modulepath[0]))
3843 -strlen(modulepath));
3844 /* No where else to look - raise an easily identifiable
3845 error, rather than leaving Windows to report
3846 "file not found" - as the user is probably blissfully
3847 unaware this shim EXE is used, and it will confuse them.
3848 (well, it confused me for a while ;-)
3849 */
3850 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003851 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00003852 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00003853 "for popen to work with your shell "
3854 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00003855 szConsoleSpawn);
3856 return FALSE;
3857 }
3858 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003859 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00003860 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003861 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00003862
Tim Peters92e4dd82002-10-05 01:47:34 +00003863 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003864 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003865 /* To maintain correct argument passing semantics,
3866 we pass the command-line as it stands, and allow
3867 quoting to be applied. w9xpopen.exe will then
3868 use its argv vector, and re-quote the necessary
3869 args for the ultimate child process.
3870 */
Tim Peters75cdad52001-11-28 22:07:30 +00003871 PyOS_snprintf(
3872 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003873 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003874 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003875 s1,
3876 s3,
3877 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003878 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00003879 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003880 dialog:
3881 "Your program accessed mem currently in use at xxx"
3882 and a hopeful warning about the stability of your
3883 system.
3884 Cost is Ctrl+C wont kill children, but anyone
3885 who cares can have a go!
3886 */
3887 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003888 }
3889 }
3890
3891 /* Could be an else here to try cmd.exe / command.com in the path
3892 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003893 else {
Tim Peters402d5982001-08-27 06:37:48 +00003894 PyErr_SetString(PyExc_RuntimeError,
3895 "Cannot locate a COMSPEC environment variable to "
3896 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00003897 return FALSE;
3898 }
Tim Peters5aa91602002-01-30 05:46:57 +00003899
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003900 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3901 siStartInfo.cb = sizeof(STARTUPINFO);
3902 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3903 siStartInfo.hStdInput = hStdin;
3904 siStartInfo.hStdOutput = hStdout;
3905 siStartInfo.hStdError = hStderr;
3906 siStartInfo.wShowWindow = SW_HIDE;
3907
3908 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003909 s2,
3910 NULL,
3911 NULL,
3912 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003913 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003914 NULL,
3915 NULL,
3916 &siStartInfo,
3917 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003918 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003919 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003920
Mark Hammondb37a3732000-08-14 04:47:33 +00003921 /* Return process handle */
3922 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003923 return TRUE;
3924 }
Tim Peters402d5982001-08-27 06:37:48 +00003925 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003926 return FALSE;
3927}
3928
3929/* The following code is based off of KB: Q190351 */
3930
3931static PyObject *
3932_PyPopen(char *cmdstring, int mode, int n)
3933{
3934 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
3935 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00003936 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00003937
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003938 SECURITY_ATTRIBUTES saAttr;
3939 BOOL fSuccess;
3940 int fd1, fd2, fd3;
3941 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00003942 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003943 PyObject *f;
3944
3945 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
3946 saAttr.bInheritHandle = TRUE;
3947 saAttr.lpSecurityDescriptor = NULL;
3948
3949 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
3950 return win32_error("CreatePipe", NULL);
3951
3952 /* Create new output read handle and the input write handle. Set
3953 * the inheritance properties to FALSE. Otherwise, the child inherits
3954 * the these handles; resulting in non-closeable handles to the pipes
3955 * being created. */
3956 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003957 GetCurrentProcess(), &hChildStdinWrDup, 0,
3958 FALSE,
3959 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003960 if (!fSuccess)
3961 return win32_error("DuplicateHandle", NULL);
3962
3963 /* Close the inheritable version of ChildStdin
3964 that we're using. */
3965 CloseHandle(hChildStdinWr);
3966
3967 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
3968 return win32_error("CreatePipe", NULL);
3969
3970 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003971 GetCurrentProcess(), &hChildStdoutRdDup, 0,
3972 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003973 if (!fSuccess)
3974 return win32_error("DuplicateHandle", NULL);
3975
3976 /* Close the inheritable version of ChildStdout
3977 that we're using. */
3978 CloseHandle(hChildStdoutRd);
3979
3980 if (n != POPEN_4) {
3981 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
3982 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003983 fSuccess = DuplicateHandle(GetCurrentProcess(),
3984 hChildStderrRd,
3985 GetCurrentProcess(),
3986 &hChildStderrRdDup, 0,
3987 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003988 if (!fSuccess)
3989 return win32_error("DuplicateHandle", NULL);
3990 /* Close the inheritable version of ChildStdErr that we're using. */
3991 CloseHandle(hChildStderrRd);
3992 }
Tim Peters5aa91602002-01-30 05:46:57 +00003993
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003994 switch (n) {
3995 case POPEN_1:
3996 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
3997 case _O_WRONLY | _O_TEXT:
3998 /* Case for writing to child Stdin in text mode. */
3999 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4000 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004001 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004002 PyFile_SetBufSize(f, 0);
4003 /* We don't care about these pipes anymore, so close them. */
4004 CloseHandle(hChildStdoutRdDup);
4005 CloseHandle(hChildStderrRdDup);
4006 break;
4007
4008 case _O_RDONLY | _O_TEXT:
4009 /* Case for reading from child Stdout in text mode. */
4010 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4011 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004012 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004013 PyFile_SetBufSize(f, 0);
4014 /* We don't care about these pipes anymore, so close them. */
4015 CloseHandle(hChildStdinWrDup);
4016 CloseHandle(hChildStderrRdDup);
4017 break;
4018
4019 case _O_RDONLY | _O_BINARY:
4020 /* Case for readinig from child Stdout in binary mode. */
4021 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4022 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004023 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004024 PyFile_SetBufSize(f, 0);
4025 /* We don't care about these pipes anymore, so close them. */
4026 CloseHandle(hChildStdinWrDup);
4027 CloseHandle(hChildStderrRdDup);
4028 break;
4029
4030 case _O_WRONLY | _O_BINARY:
4031 /* Case for writing to child Stdin in binary mode. */
4032 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4033 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004034 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004035 PyFile_SetBufSize(f, 0);
4036 /* We don't care about these pipes anymore, so close them. */
4037 CloseHandle(hChildStdoutRdDup);
4038 CloseHandle(hChildStderrRdDup);
4039 break;
4040 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004041 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004042 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004043
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004044 case POPEN_2:
4045 case POPEN_4:
4046 {
4047 char *m1, *m2;
4048 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004049
Tim Peters7dca21e2002-08-19 00:42:29 +00004050 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004051 m1 = "r";
4052 m2 = "w";
4053 } else {
4054 m1 = "rb";
4055 m2 = "wb";
4056 }
4057
4058 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4059 f1 = _fdopen(fd1, m2);
4060 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4061 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004062 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004063 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004064 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004065 PyFile_SetBufSize(p2, 0);
4066
4067 if (n != 4)
4068 CloseHandle(hChildStderrRdDup);
4069
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004070 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004071 Py_XDECREF(p1);
4072 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004073 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004074 break;
4075 }
Tim Peters5aa91602002-01-30 05:46:57 +00004076
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004077 case POPEN_3:
4078 {
4079 char *m1, *m2;
4080 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004081
Tim Peters7dca21e2002-08-19 00:42:29 +00004082 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004083 m1 = "r";
4084 m2 = "w";
4085 } else {
4086 m1 = "rb";
4087 m2 = "wb";
4088 }
4089
4090 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4091 f1 = _fdopen(fd1, m2);
4092 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4093 f2 = _fdopen(fd2, m1);
4094 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
4095 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004096 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004097 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4098 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004099 PyFile_SetBufSize(p1, 0);
4100 PyFile_SetBufSize(p2, 0);
4101 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004102 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004103 Py_XDECREF(p1);
4104 Py_XDECREF(p2);
4105 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004106 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004107 break;
4108 }
4109 }
4110
4111 if (n == POPEN_4) {
4112 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004113 hChildStdinRd,
4114 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004115 hChildStdoutWr,
4116 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004117 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004118 }
4119 else {
4120 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004121 hChildStdinRd,
4122 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004123 hChildStderrWr,
4124 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004125 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004126 }
4127
Mark Hammondb37a3732000-08-14 04:47:33 +00004128 /*
4129 * Insert the files we've created into the process dictionary
4130 * all referencing the list with the process handle and the
4131 * initial number of files (see description below in _PyPclose).
4132 * Since if _PyPclose later tried to wait on a process when all
4133 * handles weren't closed, it could create a deadlock with the
4134 * child, we spend some energy here to try to ensure that we
4135 * either insert all file handles into the dictionary or none
4136 * at all. It's a little clumsy with the various popen modes
4137 * and variable number of files involved.
4138 */
4139 if (!_PyPopenProcs) {
4140 _PyPopenProcs = PyDict_New();
4141 }
4142
4143 if (_PyPopenProcs) {
4144 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4145 int ins_rc[3];
4146
4147 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4148 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4149
4150 procObj = PyList_New(2);
4151 hProcessObj = PyLong_FromVoidPtr(hProcess);
4152 intObj = PyInt_FromLong(file_count);
4153
4154 if (procObj && hProcessObj && intObj) {
4155 PyList_SetItem(procObj,0,hProcessObj);
4156 PyList_SetItem(procObj,1,intObj);
4157
4158 fileObj[0] = PyLong_FromVoidPtr(f1);
4159 if (fileObj[0]) {
4160 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4161 fileObj[0],
4162 procObj);
4163 }
4164 if (file_count >= 2) {
4165 fileObj[1] = PyLong_FromVoidPtr(f2);
4166 if (fileObj[1]) {
4167 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4168 fileObj[1],
4169 procObj);
4170 }
4171 }
4172 if (file_count >= 3) {
4173 fileObj[2] = PyLong_FromVoidPtr(f3);
4174 if (fileObj[2]) {
4175 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4176 fileObj[2],
4177 procObj);
4178 }
4179 }
4180
4181 if (ins_rc[0] < 0 || !fileObj[0] ||
4182 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4183 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4184 /* Something failed - remove any dictionary
4185 * entries that did make it.
4186 */
4187 if (!ins_rc[0] && fileObj[0]) {
4188 PyDict_DelItem(_PyPopenProcs,
4189 fileObj[0]);
4190 }
4191 if (!ins_rc[1] && fileObj[1]) {
4192 PyDict_DelItem(_PyPopenProcs,
4193 fileObj[1]);
4194 }
4195 if (!ins_rc[2] && fileObj[2]) {
4196 PyDict_DelItem(_PyPopenProcs,
4197 fileObj[2]);
4198 }
4199 }
4200 }
Tim Peters5aa91602002-01-30 05:46:57 +00004201
Mark Hammondb37a3732000-08-14 04:47:33 +00004202 /*
4203 * Clean up our localized references for the dictionary keys
4204 * and value since PyDict_SetItem will Py_INCREF any copies
4205 * that got placed in the dictionary.
4206 */
4207 Py_XDECREF(procObj);
4208 Py_XDECREF(fileObj[0]);
4209 Py_XDECREF(fileObj[1]);
4210 Py_XDECREF(fileObj[2]);
4211 }
4212
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004213 /* Child is launched. Close the parents copy of those pipe
4214 * handles that only the child should have open. You need to
4215 * make sure that no handles to the write end of the output pipe
4216 * are maintained in this process or else the pipe will not close
4217 * when the child process exits and the ReadFile will hang. */
4218
4219 if (!CloseHandle(hChildStdinRd))
4220 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004221
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004222 if (!CloseHandle(hChildStdoutWr))
4223 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004224
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004225 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4226 return win32_error("CloseHandle", NULL);
4227
4228 return f;
4229}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004230
4231/*
4232 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4233 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004234 *
4235 * This function uses the _PyPopenProcs dictionary in order to map the
4236 * input file pointer to information about the process that was
4237 * originally created by the popen* call that created the file pointer.
4238 * The dictionary uses the file pointer as a key (with one entry
4239 * inserted for each file returned by the original popen* call) and a
4240 * single list object as the value for all files from a single call.
4241 * The list object contains the Win32 process handle at [0], and a file
4242 * count at [1], which is initialized to the total number of file
4243 * handles using that list.
4244 *
4245 * This function closes whichever handle it is passed, and decrements
4246 * the file count in the dictionary for the process handle pointed to
4247 * by this file. On the last close (when the file count reaches zero),
4248 * this function will wait for the child process and then return its
4249 * exit code as the result of the close() operation. This permits the
4250 * files to be closed in any order - it is always the close() of the
4251 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004252 *
4253 * NOTE: This function is currently called with the GIL released.
4254 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004255 */
Tim Peters736aa322000-09-01 06:51:24 +00004256
Fredrik Lundh56055a42000-07-23 19:47:12 +00004257static int _PyPclose(FILE *file)
4258{
Fredrik Lundh20318932000-07-26 17:29:12 +00004259 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004260 DWORD exit_code;
4261 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004262 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4263 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004264#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004265 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00004266#endif
4267
Fredrik Lundh20318932000-07-26 17:29:12 +00004268 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004269 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004270 */
4271 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00004272#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004273 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00004274#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004275 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004276 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4277 (procObj = PyDict_GetItem(_PyPopenProcs,
4278 fileObj)) != NULL &&
4279 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4280 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4281
4282 hProcess = PyLong_AsVoidPtr(hProcessObj);
4283 file_count = PyInt_AsLong(intObj);
4284
4285 if (file_count > 1) {
4286 /* Still other files referencing process */
4287 file_count--;
4288 PyList_SetItem(procObj,1,
4289 PyInt_FromLong(file_count));
4290 } else {
4291 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004292 if (result != EOF &&
4293 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4294 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004295 /* Possible truncation here in 16-bit environments, but
4296 * real exit codes are just the lower byte in any event.
4297 */
4298 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004299 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004300 /* Indicate failure - this will cause the file object
4301 * to raise an I/O error and translate the last Win32
4302 * error code from errno. We do have a problem with
4303 * last errors that overlap the normal errno table,
4304 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004305 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004306 if (result != EOF) {
4307 /* If the error wasn't from the fclose(), then
4308 * set errno for the file object error handling.
4309 */
4310 errno = GetLastError();
4311 }
4312 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004313 }
4314
4315 /* Free up the native handle at this point */
4316 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004317 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004318
Mark Hammondb37a3732000-08-14 04:47:33 +00004319 /* Remove this file pointer from dictionary */
4320 PyDict_DelItem(_PyPopenProcs, fileObj);
4321
4322 if (PyDict_Size(_PyPopenProcs) == 0) {
4323 Py_DECREF(_PyPopenProcs);
4324 _PyPopenProcs = NULL;
4325 }
4326
4327 } /* if object retrieval ok */
4328
4329 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004330 } /* if _PyPopenProcs */
4331
Tim Peters736aa322000-09-01 06:51:24 +00004332#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004333 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00004334#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004335 return result;
4336}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004337
4338#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004339static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004340posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004341{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004342 char *name;
4343 char *mode = "r";
4344 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004345 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004346 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004347 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004348 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004349 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004350 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004351 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004352 if (fp == NULL)
4353 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004354 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004355 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004356 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004357 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004358}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004359
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004360#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004361#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004362
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004363
Guido van Rossumb6775db1994-08-01 11:34:53 +00004364#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004365PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004366"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004367Set the current process's user id.");
4368
Barry Warsaw53699e91996-12-10 23:23:01 +00004369static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004370posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004371{
4372 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004373 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004374 return NULL;
4375 if (setuid(uid) < 0)
4376 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004377 Py_INCREF(Py_None);
4378 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004379}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004380#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004381
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004382
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004383#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004384PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004385"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004386Set the current process's effective user id.");
4387
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004388static PyObject *
4389posix_seteuid (PyObject *self, PyObject *args)
4390{
4391 int euid;
4392 if (!PyArg_ParseTuple(args, "i", &euid)) {
4393 return NULL;
4394 } else if (seteuid(euid) < 0) {
4395 return posix_error();
4396 } else {
4397 Py_INCREF(Py_None);
4398 return Py_None;
4399 }
4400}
4401#endif /* HAVE_SETEUID */
4402
4403#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004404PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004405"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004406Set the current process's effective group id.");
4407
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004408static PyObject *
4409posix_setegid (PyObject *self, PyObject *args)
4410{
4411 int egid;
4412 if (!PyArg_ParseTuple(args, "i", &egid)) {
4413 return NULL;
4414 } else if (setegid(egid) < 0) {
4415 return posix_error();
4416 } else {
4417 Py_INCREF(Py_None);
4418 return Py_None;
4419 }
4420}
4421#endif /* HAVE_SETEGID */
4422
4423#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004424PyDoc_STRVAR(posix_setreuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004425"seteuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004426Set the current process's real and effective user ids.");
4427
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004428static PyObject *
4429posix_setreuid (PyObject *self, PyObject *args)
4430{
4431 int ruid, euid;
4432 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4433 return NULL;
4434 } else if (setreuid(ruid, euid) < 0) {
4435 return posix_error();
4436 } else {
4437 Py_INCREF(Py_None);
4438 return Py_None;
4439 }
4440}
4441#endif /* HAVE_SETREUID */
4442
4443#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004444PyDoc_STRVAR(posix_setregid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004445"setegid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004446Set the current process's real and effective group ids.");
4447
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004448static PyObject *
4449posix_setregid (PyObject *self, PyObject *args)
4450{
4451 int rgid, egid;
4452 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4453 return NULL;
4454 } else if (setregid(rgid, egid) < 0) {
4455 return posix_error();
4456 } else {
4457 Py_INCREF(Py_None);
4458 return Py_None;
4459 }
4460}
4461#endif /* HAVE_SETREGID */
4462
Guido van Rossumb6775db1994-08-01 11:34:53 +00004463#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004464PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004465"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004466Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004467
Barry Warsaw53699e91996-12-10 23:23:01 +00004468static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004469posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004470{
4471 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004472 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004473 return NULL;
4474 if (setgid(gid) < 0)
4475 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004476 Py_INCREF(Py_None);
4477 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004478}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004479#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004480
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004481#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004482PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004483"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004484Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004485
4486static PyObject *
4487posix_setgroups(PyObject *self, PyObject *args)
4488{
4489 PyObject *groups;
4490 int i, len;
4491 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004492
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004493 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4494 return NULL;
4495 if (!PySequence_Check(groups)) {
4496 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4497 return NULL;
4498 }
4499 len = PySequence_Size(groups);
4500 if (len > MAX_GROUPS) {
4501 PyErr_SetString(PyExc_ValueError, "too many groups");
4502 return NULL;
4503 }
4504 for(i = 0; i < len; i++) {
4505 PyObject *elem;
4506 elem = PySequence_GetItem(groups, i);
4507 if (!elem)
4508 return NULL;
4509 if (!PyInt_Check(elem)) {
4510 PyErr_SetString(PyExc_TypeError,
4511 "groups must be integers");
4512 Py_DECREF(elem);
4513 return NULL;
4514 }
4515 /* XXX: check that value fits into gid_t. */
4516 grouplist[i] = PyInt_AsLong(elem);
4517 Py_DECREF(elem);
4518 }
4519
4520 if (setgroups(len, grouplist) < 0)
4521 return posix_error();
4522 Py_INCREF(Py_None);
4523 return Py_None;
4524}
4525#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004526
Guido van Rossumb6775db1994-08-01 11:34:53 +00004527#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004528PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004529"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004530Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004531
Barry Warsaw53699e91996-12-10 23:23:01 +00004532static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004533posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004534{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004535 int pid, options;
4536#ifdef UNION_WAIT
4537 union wait status;
4538#define status_i (status.w_status)
4539#else
4540 int status;
4541#define status_i status
4542#endif
4543 status_i = 0;
4544
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004545 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004546 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004547 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004548 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004549 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004550 if (pid == -1)
4551 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004552 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004553 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004554}
4555
Tim Petersab034fa2002-02-01 11:27:43 +00004556#elif defined(HAVE_CWAIT)
4557
4558/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004559PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004560"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004561"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004562
4563static PyObject *
4564posix_waitpid(PyObject *self, PyObject *args)
4565{
4566 int pid, options;
4567 int status;
4568
4569 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4570 return NULL;
4571 Py_BEGIN_ALLOW_THREADS
4572 pid = _cwait(&status, pid, options);
4573 Py_END_ALLOW_THREADS
4574 if (pid == -1)
4575 return posix_error();
4576 else
4577 /* shift the status left a byte so this is more like the
4578 POSIX waitpid */
4579 return Py_BuildValue("ii", pid, status << 8);
4580}
4581#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004582
Guido van Rossumad0ee831995-03-01 10:34:45 +00004583#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004584PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004585"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004586Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004587
Barry Warsaw53699e91996-12-10 23:23:01 +00004588static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004589posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004590{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004591 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004592#ifdef UNION_WAIT
4593 union wait status;
4594#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004595#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004596 int status;
4597#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004598#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00004599
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004600 status_i = 0;
4601 Py_BEGIN_ALLOW_THREADS
4602 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004603 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004604 if (pid == -1)
4605 return posix_error();
4606 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004607 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004608#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004609}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004610#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004611
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004612
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004613PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004614"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004615Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004616
Barry Warsaw53699e91996-12-10 23:23:01 +00004617static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004618posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004619{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004620#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004621 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004622#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004623#ifdef MS_WINDOWS
Mark Hammond7edd0a92003-08-06 02:46:58 +00004624 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", _wstati64);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004625#else
4626 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4627#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004628#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004629}
4630
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004631
Guido van Rossumb6775db1994-08-01 11:34:53 +00004632#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004633PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004634"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004635Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004636
Barry Warsaw53699e91996-12-10 23:23:01 +00004637static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004638posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004639{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004640 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004641 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004642 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004643 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004644 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004645 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004646 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004647 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004648 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004649 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004650 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004651}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004652#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004653
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004654
Guido van Rossumb6775db1994-08-01 11:34:53 +00004655#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004656PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004657"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00004658Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004659
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004660static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004661posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004662{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004663 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004664}
4665#endif /* HAVE_SYMLINK */
4666
4667
4668#ifdef HAVE_TIMES
4669#ifndef HZ
4670#define HZ 60 /* Universal constant :-) */
4671#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004672
Guido van Rossumd48f2521997-12-05 22:19:34 +00004673#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4674static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004675system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004676{
4677 ULONG value = 0;
4678
4679 Py_BEGIN_ALLOW_THREADS
4680 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4681 Py_END_ALLOW_THREADS
4682
4683 return value;
4684}
4685
4686static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004687posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004688{
Guido van Rossumd48f2521997-12-05 22:19:34 +00004689 /* Currently Only Uptime is Provided -- Others Later */
4690 return Py_BuildValue("ddddd",
4691 (double)0 /* t.tms_utime / HZ */,
4692 (double)0 /* t.tms_stime / HZ */,
4693 (double)0 /* t.tms_cutime / HZ */,
4694 (double)0 /* t.tms_cstime / HZ */,
4695 (double)system_uptime() / 1000);
4696}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004697#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004698static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004699posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004700{
4701 struct tms t;
4702 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00004703 errno = 0;
4704 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004705 if (c == (clock_t) -1)
4706 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004707 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004708 (double)t.tms_utime / HZ,
4709 (double)t.tms_stime / HZ,
4710 (double)t.tms_cutime / HZ,
4711 (double)t.tms_cstime / HZ,
4712 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004713}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004714#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004715#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004716
4717
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004718#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004719#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004720static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004721posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004722{
4723 FILETIME create, exit, kernel, user;
4724 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004725 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004726 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4727 /* The fields of a FILETIME structure are the hi and lo part
4728 of a 64-bit value expressed in 100 nanosecond units.
4729 1e7 is one second in such units; 1e-7 the inverse.
4730 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4731 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004732 return Py_BuildValue(
4733 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004734 (double)(kernel.dwHighDateTime*429.4967296 +
4735 kernel.dwLowDateTime*1e-7),
4736 (double)(user.dwHighDateTime*429.4967296 +
4737 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004738 (double)0,
4739 (double)0,
4740 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004741}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004742#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004743
4744#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004745PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004746"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004747Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004748#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004749
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004750
Guido van Rossumb6775db1994-08-01 11:34:53 +00004751#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004752PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004753"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004754Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004755
Barry Warsaw53699e91996-12-10 23:23:01 +00004756static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004757posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004758{
Guido van Rossum687dd131993-05-17 08:34:16 +00004759 if (setsid() < 0)
4760 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004761 Py_INCREF(Py_None);
4762 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004763}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004764#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004765
Guido van Rossumb6775db1994-08-01 11:34:53 +00004766#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004767PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004768"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004769Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004770
Barry Warsaw53699e91996-12-10 23:23:01 +00004771static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004772posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004773{
4774 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004775 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004776 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004777 if (setpgid(pid, pgrp) < 0)
4778 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004779 Py_INCREF(Py_None);
4780 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004781}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004782#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004783
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004784
Guido van Rossumb6775db1994-08-01 11:34:53 +00004785#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004786PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004787"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004788Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004789
Barry Warsaw53699e91996-12-10 23:23:01 +00004790static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004791posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004792{
4793 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004794 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004795 return NULL;
4796 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004797 if (pgid < 0)
4798 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004799 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004800}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004801#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004802
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004803
Guido van Rossumb6775db1994-08-01 11:34:53 +00004804#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004805PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004806"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004807Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004808
Barry Warsaw53699e91996-12-10 23:23:01 +00004809static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004810posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004811{
4812 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004813 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004814 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004815 if (tcsetpgrp(fd, pgid) < 0)
4816 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004817 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004818 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004819}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004820#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004821
Guido van Rossum687dd131993-05-17 08:34:16 +00004822/* Functions acting on file descriptors */
4823
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004824PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004825"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004826Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004827
Barry Warsaw53699e91996-12-10 23:23:01 +00004828static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004829posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004830{
Mark Hammondef8b6542001-05-13 08:04:26 +00004831 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004832 int flag;
4833 int mode = 0777;
4834 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004835
4836#ifdef MS_WINDOWS
4837 if (unicode_file_names()) {
4838 PyUnicodeObject *po;
4839 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4840 Py_BEGIN_ALLOW_THREADS
4841 /* PyUnicode_AS_UNICODE OK without thread
4842 lock as it is a simple dereference. */
4843 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4844 Py_END_ALLOW_THREADS
4845 if (fd < 0)
4846 return posix_error();
4847 return PyInt_FromLong((long)fd);
4848 }
4849 /* Drop the argument parsing error as narrow strings
4850 are also valid. */
4851 PyErr_Clear();
4852 }
4853#endif
4854
Tim Peters5aa91602002-01-30 05:46:57 +00004855 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004856 Py_FileSystemDefaultEncoding, &file,
4857 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004858 return NULL;
4859
Barry Warsaw53699e91996-12-10 23:23:01 +00004860 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004861 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004862 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004863 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004864 return posix_error_with_allocated_filename(file);
4865 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004866 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004867}
4868
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004869
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004870PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004871"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004872Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004873
Barry Warsaw53699e91996-12-10 23:23:01 +00004874static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004875posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004876{
4877 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004878 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004879 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004880 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004881 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004882 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004883 if (res < 0)
4884 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004885 Py_INCREF(Py_None);
4886 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004887}
4888
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004889
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004890PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004891"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004892Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004893
Barry Warsaw53699e91996-12-10 23:23:01 +00004894static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004895posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004896{
4897 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004898 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004899 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004900 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004901 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004902 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004903 if (fd < 0)
4904 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004905 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004906}
4907
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004908
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004909PyDoc_STRVAR(posix_dup2__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004910"dup2(fd, fd2)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004911Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004912
Barry Warsaw53699e91996-12-10 23:23:01 +00004913static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004914posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004915{
4916 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004917 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004918 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004919 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004920 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004921 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004922 if (res < 0)
4923 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004924 Py_INCREF(Py_None);
4925 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004926}
4927
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004928
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004929PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004930"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004931Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004932
Barry Warsaw53699e91996-12-10 23:23:01 +00004933static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004934posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004935{
4936 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004937#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00004938 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004939#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004940 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004941#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004942 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004943 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004944 return NULL;
4945#ifdef SEEK_SET
4946 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4947 switch (how) {
4948 case 0: how = SEEK_SET; break;
4949 case 1: how = SEEK_CUR; break;
4950 case 2: how = SEEK_END; break;
4951 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004952#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004953
4954#if !defined(HAVE_LARGEFILE_SUPPORT)
4955 pos = PyInt_AsLong(posobj);
4956#else
4957 pos = PyLong_Check(posobj) ?
4958 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4959#endif
4960 if (PyErr_Occurred())
4961 return NULL;
4962
Barry Warsaw53699e91996-12-10 23:23:01 +00004963 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004964#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004965 res = _lseeki64(fd, pos, how);
4966#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004967 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004968#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004969 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004970 if (res < 0)
4971 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004972
4973#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00004974 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004975#else
4976 return PyLong_FromLongLong(res);
4977#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004978}
4979
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004980
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004981PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004982"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004983Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004984
Barry Warsaw53699e91996-12-10 23:23:01 +00004985static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004986posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004987{
Guido van Rossum8bac5461996-06-11 18:38:48 +00004988 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004989 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004990 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004991 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004992 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004993 if (buffer == NULL)
4994 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004995 Py_BEGIN_ALLOW_THREADS
4996 n = read(fd, PyString_AsString(buffer), size);
4997 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004998 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004999 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005000 return posix_error();
5001 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005002 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005003 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005004 return buffer;
5005}
5006
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005007
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005008PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005009"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005010Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005011
Barry Warsaw53699e91996-12-10 23:23:01 +00005012static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005013posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005014{
5015 int fd, size;
5016 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005017 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005018 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005019 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005020 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005021 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005022 if (size < 0)
5023 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005024 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005025}
5026
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005027
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005028PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005029"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005030Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005031
Barry Warsaw53699e91996-12-10 23:23:01 +00005032static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005033posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005034{
5035 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005036 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005037 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005038 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005039 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005040#ifdef __VMS
5041 /* on OpenVMS we must ensure that all bytes are written to the file */
5042 fsync(fd);
5043#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005044 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005045 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005046 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005047 if (res != 0)
5048 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00005049
Fred Drake699f3522000-06-29 21:12:41 +00005050 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005051}
5052
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005053
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005054PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005055"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005056Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005057
Barry Warsaw53699e91996-12-10 23:23:01 +00005058static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005059posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005060{
Guido van Rossum687dd131993-05-17 08:34:16 +00005061 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005062 char *mode = "r";
5063 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005064 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005065 PyObject *f;
5066 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005067 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005068
Thomas Heller1f043e22002-11-07 16:00:59 +00005069 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5070 PyErr_Format(PyExc_ValueError,
5071 "invalid file mode '%s'", mode);
5072 return NULL;
5073 }
5074
Barry Warsaw53699e91996-12-10 23:23:01 +00005075 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005076 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005077 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005078 if (fp == NULL)
5079 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005080 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005081 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005082 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005083 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005084}
5085
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005086PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005087"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005088Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005089connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005090
5091static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005092posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005093{
5094 int fd;
5095 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5096 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005097 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005098}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005099
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005100#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005101PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005102"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005103Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005104
Barry Warsaw53699e91996-12-10 23:23:01 +00005105static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005106posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005107{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005108#if defined(PYOS_OS2)
5109 HFILE read, write;
5110 APIRET rc;
5111
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005112 Py_BEGIN_ALLOW_THREADS
5113 rc = DosCreatePipe( &read, &write, 4096);
5114 Py_END_ALLOW_THREADS
5115 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005116 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005117
5118 return Py_BuildValue("(ii)", read, write);
5119#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005120#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005121 int fds[2];
5122 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005123 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005124 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005125 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005126 if (res != 0)
5127 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005128 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005129#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005130 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005131 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005132 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005133 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005134 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005135 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005136 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005137 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005138 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5139 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005140 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005141#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005142#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005143}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005144#endif /* HAVE_PIPE */
5145
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005146
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005147#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005148PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005149"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005150Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005151
Barry Warsaw53699e91996-12-10 23:23:01 +00005152static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005153posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005154{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005155 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005156 int mode = 0666;
5157 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005158 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005159 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005160 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005161 res = mkfifo(filename, mode);
5162 Py_END_ALLOW_THREADS
5163 if (res < 0)
5164 return posix_error();
5165 Py_INCREF(Py_None);
5166 return Py_None;
5167}
5168#endif
5169
5170
Neal Norwitz11690112002-07-30 01:08:28 +00005171#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005172PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005173"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005174Create a filesystem node (file, device special file or named pipe)\n\
5175named filename. mode specifies both the permissions to use and the\n\
5176type of node to be created, being combined (bitwise OR) with one of\n\
5177S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005178device defines the newly created device special file (probably using\n\
5179os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005180
5181
5182static PyObject *
5183posix_mknod(PyObject *self, PyObject *args)
5184{
5185 char *filename;
5186 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005187 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005188 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005189 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005190 return NULL;
5191 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005192 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005193 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005194 if (res < 0)
5195 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005196 Py_INCREF(Py_None);
5197 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005198}
5199#endif
5200
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005201#ifdef HAVE_DEVICE_MACROS
5202PyDoc_STRVAR(posix_major__doc__,
5203"major(device) -> major number\n\
5204Extracts a device major number from a raw device number.");
5205
5206static PyObject *
5207posix_major(PyObject *self, PyObject *args)
5208{
5209 int device;
5210 if (!PyArg_ParseTuple(args, "i:major", &device))
5211 return NULL;
5212 return PyInt_FromLong((long)major(device));
5213}
5214
5215PyDoc_STRVAR(posix_minor__doc__,
5216"minor(device) -> minor number\n\
5217Extracts a device minor number from a raw device number.");
5218
5219static PyObject *
5220posix_minor(PyObject *self, PyObject *args)
5221{
5222 int device;
5223 if (!PyArg_ParseTuple(args, "i:minor", &device))
5224 return NULL;
5225 return PyInt_FromLong((long)minor(device));
5226}
5227
5228PyDoc_STRVAR(posix_makedev__doc__,
5229"makedev(major, minor) -> device number\n\
5230Composes a raw device number from the major and minor device numbers.");
5231
5232static PyObject *
5233posix_makedev(PyObject *self, PyObject *args)
5234{
5235 int major, minor;
5236 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5237 return NULL;
5238 return PyInt_FromLong((long)makedev(major, minor));
5239}
5240#endif /* device macros */
5241
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005242
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005243#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005244PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005245"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005246Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005247
Barry Warsaw53699e91996-12-10 23:23:01 +00005248static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005249posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005250{
5251 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005252 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005253 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005254 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005255
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005256 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005257 return NULL;
5258
5259#if !defined(HAVE_LARGEFILE_SUPPORT)
5260 length = PyInt_AsLong(lenobj);
5261#else
5262 length = PyLong_Check(lenobj) ?
5263 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5264#endif
5265 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005266 return NULL;
5267
Barry Warsaw53699e91996-12-10 23:23:01 +00005268 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005269 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005270 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005271 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005272 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005273 return NULL;
5274 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005275 Py_INCREF(Py_None);
5276 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005277}
5278#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005279
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005280#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005281PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005282"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005283Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005284
Fred Drake762e2061999-08-26 17:23:54 +00005285/* Save putenv() parameters as values here, so we can collect them when they
5286 * get re-set with another call for the same key. */
5287static PyObject *posix_putenv_garbage;
5288
Tim Peters5aa91602002-01-30 05:46:57 +00005289static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005290posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005291{
5292 char *s1, *s2;
5293 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005294 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005295 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005296
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005297 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005298 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005299
5300#if defined(PYOS_OS2)
5301 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5302 APIRET rc;
5303
Guido van Rossumd48f2521997-12-05 22:19:34 +00005304 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5305 if (rc != NO_ERROR)
5306 return os2_error(rc);
5307
5308 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5309 APIRET rc;
5310
Guido van Rossumd48f2521997-12-05 22:19:34 +00005311 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5312 if (rc != NO_ERROR)
5313 return os2_error(rc);
5314 } else {
5315#endif
5316
Fred Drake762e2061999-08-26 17:23:54 +00005317 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005318 len = strlen(s1) + strlen(s2) + 2;
5319 /* len includes space for a trailing \0; the size arg to
5320 PyString_FromStringAndSize does not count that */
5321 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005322 if (newstr == NULL)
5323 return PyErr_NoMemory();
5324 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005325 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005326 if (putenv(new)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005327 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005328 posix_error();
5329 return NULL;
5330 }
Fred Drake762e2061999-08-26 17:23:54 +00005331 /* Install the first arg and newstr in posix_putenv_garbage;
5332 * this will cause previous value to be collected. This has to
5333 * happen after the real putenv() call because the old value
5334 * was still accessible until then. */
5335 if (PyDict_SetItem(posix_putenv_garbage,
5336 PyTuple_GET_ITEM(args, 0), newstr)) {
5337 /* really not much we can do; just leak */
5338 PyErr_Clear();
5339 }
5340 else {
5341 Py_DECREF(newstr);
5342 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005343
5344#if defined(PYOS_OS2)
5345 }
5346#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005347 Py_INCREF(Py_None);
5348 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005349}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005350#endif /* putenv */
5351
Guido van Rossumc524d952001-10-19 01:31:59 +00005352#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005353PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005354"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005355Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005356
5357static PyObject *
5358posix_unsetenv(PyObject *self, PyObject *args)
5359{
5360 char *s1;
5361
5362 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5363 return NULL;
5364
5365 unsetenv(s1);
5366
5367 /* Remove the key from posix_putenv_garbage;
5368 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005369 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005370 * old value was still accessible until then.
5371 */
5372 if (PyDict_DelItem(posix_putenv_garbage,
5373 PyTuple_GET_ITEM(args, 0))) {
5374 /* really not much we can do; just leak */
5375 PyErr_Clear();
5376 }
5377
5378 Py_INCREF(Py_None);
5379 return Py_None;
5380}
5381#endif /* unsetenv */
5382
Guido van Rossumb6a47161997-09-15 22:54:34 +00005383#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005384PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005385"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005386Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005387
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005388static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005389posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005390{
5391 int code;
5392 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005393 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005394 return NULL;
5395 message = strerror(code);
5396 if (message == NULL) {
5397 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005398 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005399 return NULL;
5400 }
5401 return PyString_FromString(message);
5402}
5403#endif /* strerror */
5404
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005405
Guido van Rossumc9641791998-08-04 15:26:23 +00005406#ifdef HAVE_SYS_WAIT_H
5407
Fred Drake106c1a02002-04-23 15:58:02 +00005408#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005409PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005410"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005411Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005412
5413static PyObject *
5414posix_WCOREDUMP(PyObject *self, PyObject *args)
5415{
5416#ifdef UNION_WAIT
5417 union wait status;
5418#define status_i (status.w_status)
5419#else
5420 int status;
5421#define status_i status
5422#endif
5423 status_i = 0;
5424
5425 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
5426 {
5427 return NULL;
5428 }
5429
5430 return PyBool_FromLong(WCOREDUMP(status));
5431#undef status_i
5432}
5433#endif /* WCOREDUMP */
5434
5435#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005436PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005437"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005438Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005439job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005440
5441static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005442posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005443{
5444#ifdef UNION_WAIT
5445 union wait status;
5446#define status_i (status.w_status)
5447#else
5448 int status;
5449#define status_i status
5450#endif
5451 status_i = 0;
5452
5453 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
5454 {
5455 return NULL;
5456 }
5457
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005458 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005459#undef status_i
5460}
5461#endif /* WIFCONTINUED */
5462
Guido van Rossumc9641791998-08-04 15:26:23 +00005463#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005464PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005465"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005466Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005467
5468static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005469posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005470{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005471#ifdef UNION_WAIT
5472 union wait status;
5473#define status_i (status.w_status)
5474#else
5475 int status;
5476#define status_i status
5477#endif
5478 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005479
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005480 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005481 {
5482 return NULL;
5483 }
Tim Peters5aa91602002-01-30 05:46:57 +00005484
Fred Drake106c1a02002-04-23 15:58:02 +00005485 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005486#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005487}
5488#endif /* WIFSTOPPED */
5489
5490#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005491PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005492"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005493Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005494
5495static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005496posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005497{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005498#ifdef UNION_WAIT
5499 union wait status;
5500#define status_i (status.w_status)
5501#else
5502 int status;
5503#define status_i status
5504#endif
5505 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005506
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005507 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005508 {
5509 return NULL;
5510 }
Tim Peters5aa91602002-01-30 05:46:57 +00005511
Fred Drake106c1a02002-04-23 15:58:02 +00005512 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005513#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005514}
5515#endif /* WIFSIGNALED */
5516
5517#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005518PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005519"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005520Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005521system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005522
5523static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005524posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005525{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005526#ifdef UNION_WAIT
5527 union wait status;
5528#define status_i (status.w_status)
5529#else
5530 int status;
5531#define status_i status
5532#endif
5533 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005534
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005535 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005536 {
5537 return NULL;
5538 }
Tim Peters5aa91602002-01-30 05:46:57 +00005539
Fred Drake106c1a02002-04-23 15:58:02 +00005540 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005541#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005542}
5543#endif /* WIFEXITED */
5544
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005545#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005546PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005547"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005548Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005549
5550static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005551posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005552{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005553#ifdef UNION_WAIT
5554 union wait status;
5555#define status_i (status.w_status)
5556#else
5557 int status;
5558#define status_i status
5559#endif
5560 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005561
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005562 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005563 {
5564 return NULL;
5565 }
Tim Peters5aa91602002-01-30 05:46:57 +00005566
Guido van Rossumc9641791998-08-04 15:26:23 +00005567 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005568#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005569}
5570#endif /* WEXITSTATUS */
5571
5572#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005573PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005574"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005575Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005576value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005577
5578static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005579posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005580{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005581#ifdef UNION_WAIT
5582 union wait status;
5583#define status_i (status.w_status)
5584#else
5585 int status;
5586#define status_i status
5587#endif
5588 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005589
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005590 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005591 {
5592 return NULL;
5593 }
Tim Peters5aa91602002-01-30 05:46:57 +00005594
Guido van Rossumc9641791998-08-04 15:26:23 +00005595 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005596#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005597}
5598#endif /* WTERMSIG */
5599
5600#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005601PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005602"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005603Return the signal that stopped the process that provided\n\
5604the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005605
5606static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005607posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005608{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005609#ifdef UNION_WAIT
5610 union wait status;
5611#define status_i (status.w_status)
5612#else
5613 int status;
5614#define status_i status
5615#endif
5616 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005617
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005618 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005619 {
5620 return NULL;
5621 }
Tim Peters5aa91602002-01-30 05:46:57 +00005622
Guido van Rossumc9641791998-08-04 15:26:23 +00005623 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005624#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005625}
5626#endif /* WSTOPSIG */
5627
5628#endif /* HAVE_SYS_WAIT_H */
5629
5630
Guido van Rossum94f6f721999-01-06 18:42:14 +00005631#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005632#ifdef _SCO_DS
5633/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5634 needed definitions in sys/statvfs.h */
5635#define _SVID3
5636#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005637#include <sys/statvfs.h>
5638
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005639static PyObject*
5640_pystatvfs_fromstructstatvfs(struct statvfs st) {
5641 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5642 if (v == NULL)
5643 return NULL;
5644
5645#if !defined(HAVE_LARGEFILE_SUPPORT)
5646 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5647 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5648 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5649 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5650 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5651 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5652 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5653 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5654 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5655 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5656#else
5657 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5658 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005659 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005660 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005661 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005662 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005663 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005664 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005665 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005666 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005667 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005668 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005669 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005670 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005671 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5672 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5673#endif
5674
5675 return v;
5676}
5677
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005678PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005679"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005680Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005681
5682static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005683posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005684{
5685 int fd, res;
5686 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005687
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005688 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005689 return NULL;
5690 Py_BEGIN_ALLOW_THREADS
5691 res = fstatvfs(fd, &st);
5692 Py_END_ALLOW_THREADS
5693 if (res != 0)
5694 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005695
5696 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005697}
5698#endif /* HAVE_FSTATVFS */
5699
5700
5701#if defined(HAVE_STATVFS)
5702#include <sys/statvfs.h>
5703
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005704PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005705"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005706Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005707
5708static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005709posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005710{
5711 char *path;
5712 int res;
5713 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005714 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005715 return NULL;
5716 Py_BEGIN_ALLOW_THREADS
5717 res = statvfs(path, &st);
5718 Py_END_ALLOW_THREADS
5719 if (res != 0)
5720 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005721
5722 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005723}
5724#endif /* HAVE_STATVFS */
5725
5726
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005727#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005728PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005729"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005730Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00005731The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005732or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005733
5734static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005735posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005736{
5737 PyObject *result = NULL;
5738 char *dir = NULL;
5739 char *pfx = NULL;
5740 char *name;
5741
5742 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5743 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005744
5745 if (PyErr_Warn(PyExc_RuntimeWarning,
5746 "tempnam is a potential security risk to your program") < 0)
5747 return NULL;
5748
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005749#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00005750 name = _tempnam(dir, pfx);
5751#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005752 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005753#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005754 if (name == NULL)
5755 return PyErr_NoMemory();
5756 result = PyString_FromString(name);
5757 free(name);
5758 return result;
5759}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005760#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005761
5762
5763#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005764PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005765"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005766Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005767
5768static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005769posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005770{
5771 FILE *fp;
5772
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005773 fp = tmpfile();
5774 if (fp == NULL)
5775 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00005776 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005777}
5778#endif
5779
5780
5781#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005782PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005783"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005784Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005785
5786static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005787posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005788{
5789 char buffer[L_tmpnam];
5790 char *name;
5791
Skip Montanaro95618b52001-08-18 18:52:10 +00005792 if (PyErr_Warn(PyExc_RuntimeWarning,
5793 "tmpnam is a potential security risk to your program") < 0)
5794 return NULL;
5795
Greg Wardb48bc172000-03-01 21:51:56 +00005796#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005797 name = tmpnam_r(buffer);
5798#else
5799 name = tmpnam(buffer);
5800#endif
5801 if (name == NULL) {
5802 PyErr_SetObject(PyExc_OSError,
5803 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005804#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005805 "unexpected NULL from tmpnam_r"
5806#else
5807 "unexpected NULL from tmpnam"
5808#endif
5809 ));
5810 return NULL;
5811 }
5812 return PyString_FromString(buffer);
5813}
5814#endif
5815
5816
Fred Drakec9680921999-12-13 16:37:25 +00005817/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5818 * It maps strings representing configuration variable names to
5819 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005820 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005821 * rarely-used constants. There are three separate tables that use
5822 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005823 *
5824 * This code is always included, even if none of the interfaces that
5825 * need it are included. The #if hackery needed to avoid it would be
5826 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005827 */
5828struct constdef {
5829 char *name;
5830 long value;
5831};
5832
Fred Drake12c6e2d1999-12-14 21:25:03 +00005833static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005834conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5835 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005836{
5837 if (PyInt_Check(arg)) {
5838 *valuep = PyInt_AS_LONG(arg);
5839 return 1;
5840 }
5841 if (PyString_Check(arg)) {
5842 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005843 size_t lo = 0;
5844 size_t mid;
5845 size_t hi = tablesize;
5846 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005847 char *confname = PyString_AS_STRING(arg);
5848 while (lo < hi) {
5849 mid = (lo + hi) / 2;
5850 cmp = strcmp(confname, table[mid].name);
5851 if (cmp < 0)
5852 hi = mid;
5853 else if (cmp > 0)
5854 lo = mid + 1;
5855 else {
5856 *valuep = table[mid].value;
5857 return 1;
5858 }
5859 }
5860 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5861 }
5862 else
5863 PyErr_SetString(PyExc_TypeError,
5864 "configuration names must be strings or integers");
5865 return 0;
5866}
5867
5868
5869#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5870static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005871#ifdef _PC_ABI_AIO_XFER_MAX
5872 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5873#endif
5874#ifdef _PC_ABI_ASYNC_IO
5875 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5876#endif
Fred Drakec9680921999-12-13 16:37:25 +00005877#ifdef _PC_ASYNC_IO
5878 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5879#endif
5880#ifdef _PC_CHOWN_RESTRICTED
5881 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5882#endif
5883#ifdef _PC_FILESIZEBITS
5884 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5885#endif
5886#ifdef _PC_LAST
5887 {"PC_LAST", _PC_LAST},
5888#endif
5889#ifdef _PC_LINK_MAX
5890 {"PC_LINK_MAX", _PC_LINK_MAX},
5891#endif
5892#ifdef _PC_MAX_CANON
5893 {"PC_MAX_CANON", _PC_MAX_CANON},
5894#endif
5895#ifdef _PC_MAX_INPUT
5896 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5897#endif
5898#ifdef _PC_NAME_MAX
5899 {"PC_NAME_MAX", _PC_NAME_MAX},
5900#endif
5901#ifdef _PC_NO_TRUNC
5902 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5903#endif
5904#ifdef _PC_PATH_MAX
5905 {"PC_PATH_MAX", _PC_PATH_MAX},
5906#endif
5907#ifdef _PC_PIPE_BUF
5908 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5909#endif
5910#ifdef _PC_PRIO_IO
5911 {"PC_PRIO_IO", _PC_PRIO_IO},
5912#endif
5913#ifdef _PC_SOCK_MAXBUF
5914 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5915#endif
5916#ifdef _PC_SYNC_IO
5917 {"PC_SYNC_IO", _PC_SYNC_IO},
5918#endif
5919#ifdef _PC_VDISABLE
5920 {"PC_VDISABLE", _PC_VDISABLE},
5921#endif
5922};
5923
Fred Drakec9680921999-12-13 16:37:25 +00005924static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005925conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005926{
5927 return conv_confname(arg, valuep, posix_constants_pathconf,
5928 sizeof(posix_constants_pathconf)
5929 / sizeof(struct constdef));
5930}
5931#endif
5932
5933#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005934PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005935"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005936Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005937If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005938
5939static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005940posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005941{
5942 PyObject *result = NULL;
5943 int name, fd;
5944
Fred Drake12c6e2d1999-12-14 21:25:03 +00005945 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5946 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005947 long limit;
5948
5949 errno = 0;
5950 limit = fpathconf(fd, name);
5951 if (limit == -1 && errno != 0)
5952 posix_error();
5953 else
5954 result = PyInt_FromLong(limit);
5955 }
5956 return result;
5957}
5958#endif
5959
5960
5961#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005962PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005963"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005964Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005965If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005966
5967static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005968posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005969{
5970 PyObject *result = NULL;
5971 int name;
5972 char *path;
5973
5974 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5975 conv_path_confname, &name)) {
5976 long limit;
5977
5978 errno = 0;
5979 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005980 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005981 if (errno == EINVAL)
5982 /* could be a path or name problem */
5983 posix_error();
5984 else
5985 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005986 }
Fred Drakec9680921999-12-13 16:37:25 +00005987 else
5988 result = PyInt_FromLong(limit);
5989 }
5990 return result;
5991}
5992#endif
5993
5994#ifdef HAVE_CONFSTR
5995static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005996#ifdef _CS_ARCHITECTURE
5997 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5998#endif
5999#ifdef _CS_HOSTNAME
6000 {"CS_HOSTNAME", _CS_HOSTNAME},
6001#endif
6002#ifdef _CS_HW_PROVIDER
6003 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6004#endif
6005#ifdef _CS_HW_SERIAL
6006 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6007#endif
6008#ifdef _CS_INITTAB_NAME
6009 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6010#endif
Fred Drakec9680921999-12-13 16:37:25 +00006011#ifdef _CS_LFS64_CFLAGS
6012 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6013#endif
6014#ifdef _CS_LFS64_LDFLAGS
6015 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6016#endif
6017#ifdef _CS_LFS64_LIBS
6018 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6019#endif
6020#ifdef _CS_LFS64_LINTFLAGS
6021 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6022#endif
6023#ifdef _CS_LFS_CFLAGS
6024 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6025#endif
6026#ifdef _CS_LFS_LDFLAGS
6027 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6028#endif
6029#ifdef _CS_LFS_LIBS
6030 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6031#endif
6032#ifdef _CS_LFS_LINTFLAGS
6033 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6034#endif
Fred Draked86ed291999-12-15 15:34:33 +00006035#ifdef _CS_MACHINE
6036 {"CS_MACHINE", _CS_MACHINE},
6037#endif
Fred Drakec9680921999-12-13 16:37:25 +00006038#ifdef _CS_PATH
6039 {"CS_PATH", _CS_PATH},
6040#endif
Fred Draked86ed291999-12-15 15:34:33 +00006041#ifdef _CS_RELEASE
6042 {"CS_RELEASE", _CS_RELEASE},
6043#endif
6044#ifdef _CS_SRPC_DOMAIN
6045 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6046#endif
6047#ifdef _CS_SYSNAME
6048 {"CS_SYSNAME", _CS_SYSNAME},
6049#endif
6050#ifdef _CS_VERSION
6051 {"CS_VERSION", _CS_VERSION},
6052#endif
Fred Drakec9680921999-12-13 16:37:25 +00006053#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6054 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6055#endif
6056#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6057 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6058#endif
6059#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6060 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6061#endif
6062#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6063 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6064#endif
6065#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6066 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6067#endif
6068#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6069 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6070#endif
6071#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6072 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6073#endif
6074#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6075 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6076#endif
6077#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6078 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6079#endif
6080#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6081 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6082#endif
6083#ifdef _CS_XBS5_LP64_OFF64_LIBS
6084 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6085#endif
6086#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6087 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6088#endif
6089#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6090 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6091#endif
6092#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6093 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6094#endif
6095#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6096 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6097#endif
6098#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6099 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6100#endif
Fred Draked86ed291999-12-15 15:34:33 +00006101#ifdef _MIPS_CS_AVAIL_PROCESSORS
6102 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6103#endif
6104#ifdef _MIPS_CS_BASE
6105 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6106#endif
6107#ifdef _MIPS_CS_HOSTID
6108 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6109#endif
6110#ifdef _MIPS_CS_HW_NAME
6111 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6112#endif
6113#ifdef _MIPS_CS_NUM_PROCESSORS
6114 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6115#endif
6116#ifdef _MIPS_CS_OSREL_MAJ
6117 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6118#endif
6119#ifdef _MIPS_CS_OSREL_MIN
6120 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6121#endif
6122#ifdef _MIPS_CS_OSREL_PATCH
6123 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6124#endif
6125#ifdef _MIPS_CS_OS_NAME
6126 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6127#endif
6128#ifdef _MIPS_CS_OS_PROVIDER
6129 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6130#endif
6131#ifdef _MIPS_CS_PROCESSORS
6132 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6133#endif
6134#ifdef _MIPS_CS_SERIAL
6135 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6136#endif
6137#ifdef _MIPS_CS_VENDOR
6138 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6139#endif
Fred Drakec9680921999-12-13 16:37:25 +00006140};
6141
6142static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006143conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006144{
6145 return conv_confname(arg, valuep, posix_constants_confstr,
6146 sizeof(posix_constants_confstr)
6147 / sizeof(struct constdef));
6148}
6149
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006150PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006151"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006152Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006153
6154static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006155posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006156{
6157 PyObject *result = NULL;
6158 int name;
6159 char buffer[64];
6160
6161 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6162 int len = confstr(name, buffer, sizeof(buffer));
6163
Fred Drakec9680921999-12-13 16:37:25 +00006164 errno = 0;
6165 if (len == 0) {
6166 if (errno != 0)
6167 posix_error();
6168 else
6169 result = PyString_FromString("");
6170 }
6171 else {
6172 if (len >= sizeof(buffer)) {
6173 result = PyString_FromStringAndSize(NULL, len);
6174 if (result != NULL)
6175 confstr(name, PyString_AS_STRING(result), len+1);
6176 }
6177 else
6178 result = PyString_FromString(buffer);
6179 }
6180 }
6181 return result;
6182}
6183#endif
6184
6185
6186#ifdef HAVE_SYSCONF
6187static struct constdef posix_constants_sysconf[] = {
6188#ifdef _SC_2_CHAR_TERM
6189 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6190#endif
6191#ifdef _SC_2_C_BIND
6192 {"SC_2_C_BIND", _SC_2_C_BIND},
6193#endif
6194#ifdef _SC_2_C_DEV
6195 {"SC_2_C_DEV", _SC_2_C_DEV},
6196#endif
6197#ifdef _SC_2_C_VERSION
6198 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6199#endif
6200#ifdef _SC_2_FORT_DEV
6201 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6202#endif
6203#ifdef _SC_2_FORT_RUN
6204 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6205#endif
6206#ifdef _SC_2_LOCALEDEF
6207 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6208#endif
6209#ifdef _SC_2_SW_DEV
6210 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6211#endif
6212#ifdef _SC_2_UPE
6213 {"SC_2_UPE", _SC_2_UPE},
6214#endif
6215#ifdef _SC_2_VERSION
6216 {"SC_2_VERSION", _SC_2_VERSION},
6217#endif
Fred Draked86ed291999-12-15 15:34:33 +00006218#ifdef _SC_ABI_ASYNCHRONOUS_IO
6219 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6220#endif
6221#ifdef _SC_ACL
6222 {"SC_ACL", _SC_ACL},
6223#endif
Fred Drakec9680921999-12-13 16:37:25 +00006224#ifdef _SC_AIO_LISTIO_MAX
6225 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6226#endif
Fred Drakec9680921999-12-13 16:37:25 +00006227#ifdef _SC_AIO_MAX
6228 {"SC_AIO_MAX", _SC_AIO_MAX},
6229#endif
6230#ifdef _SC_AIO_PRIO_DELTA_MAX
6231 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6232#endif
6233#ifdef _SC_ARG_MAX
6234 {"SC_ARG_MAX", _SC_ARG_MAX},
6235#endif
6236#ifdef _SC_ASYNCHRONOUS_IO
6237 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6238#endif
6239#ifdef _SC_ATEXIT_MAX
6240 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6241#endif
Fred Draked86ed291999-12-15 15:34:33 +00006242#ifdef _SC_AUDIT
6243 {"SC_AUDIT", _SC_AUDIT},
6244#endif
Fred Drakec9680921999-12-13 16:37:25 +00006245#ifdef _SC_AVPHYS_PAGES
6246 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6247#endif
6248#ifdef _SC_BC_BASE_MAX
6249 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6250#endif
6251#ifdef _SC_BC_DIM_MAX
6252 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6253#endif
6254#ifdef _SC_BC_SCALE_MAX
6255 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6256#endif
6257#ifdef _SC_BC_STRING_MAX
6258 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6259#endif
Fred Draked86ed291999-12-15 15:34:33 +00006260#ifdef _SC_CAP
6261 {"SC_CAP", _SC_CAP},
6262#endif
Fred Drakec9680921999-12-13 16:37:25 +00006263#ifdef _SC_CHARCLASS_NAME_MAX
6264 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6265#endif
6266#ifdef _SC_CHAR_BIT
6267 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6268#endif
6269#ifdef _SC_CHAR_MAX
6270 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6271#endif
6272#ifdef _SC_CHAR_MIN
6273 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6274#endif
6275#ifdef _SC_CHILD_MAX
6276 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6277#endif
6278#ifdef _SC_CLK_TCK
6279 {"SC_CLK_TCK", _SC_CLK_TCK},
6280#endif
6281#ifdef _SC_COHER_BLKSZ
6282 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6283#endif
6284#ifdef _SC_COLL_WEIGHTS_MAX
6285 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6286#endif
6287#ifdef _SC_DCACHE_ASSOC
6288 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6289#endif
6290#ifdef _SC_DCACHE_BLKSZ
6291 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6292#endif
6293#ifdef _SC_DCACHE_LINESZ
6294 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6295#endif
6296#ifdef _SC_DCACHE_SZ
6297 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6298#endif
6299#ifdef _SC_DCACHE_TBLKSZ
6300 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6301#endif
6302#ifdef _SC_DELAYTIMER_MAX
6303 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6304#endif
6305#ifdef _SC_EQUIV_CLASS_MAX
6306 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6307#endif
6308#ifdef _SC_EXPR_NEST_MAX
6309 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6310#endif
6311#ifdef _SC_FSYNC
6312 {"SC_FSYNC", _SC_FSYNC},
6313#endif
6314#ifdef _SC_GETGR_R_SIZE_MAX
6315 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6316#endif
6317#ifdef _SC_GETPW_R_SIZE_MAX
6318 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6319#endif
6320#ifdef _SC_ICACHE_ASSOC
6321 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6322#endif
6323#ifdef _SC_ICACHE_BLKSZ
6324 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6325#endif
6326#ifdef _SC_ICACHE_LINESZ
6327 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6328#endif
6329#ifdef _SC_ICACHE_SZ
6330 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6331#endif
Fred Draked86ed291999-12-15 15:34:33 +00006332#ifdef _SC_INF
6333 {"SC_INF", _SC_INF},
6334#endif
Fred Drakec9680921999-12-13 16:37:25 +00006335#ifdef _SC_INT_MAX
6336 {"SC_INT_MAX", _SC_INT_MAX},
6337#endif
6338#ifdef _SC_INT_MIN
6339 {"SC_INT_MIN", _SC_INT_MIN},
6340#endif
6341#ifdef _SC_IOV_MAX
6342 {"SC_IOV_MAX", _SC_IOV_MAX},
6343#endif
Fred Draked86ed291999-12-15 15:34:33 +00006344#ifdef _SC_IP_SECOPTS
6345 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6346#endif
Fred Drakec9680921999-12-13 16:37:25 +00006347#ifdef _SC_JOB_CONTROL
6348 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6349#endif
Fred Draked86ed291999-12-15 15:34:33 +00006350#ifdef _SC_KERN_POINTERS
6351 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6352#endif
6353#ifdef _SC_KERN_SIM
6354 {"SC_KERN_SIM", _SC_KERN_SIM},
6355#endif
Fred Drakec9680921999-12-13 16:37:25 +00006356#ifdef _SC_LINE_MAX
6357 {"SC_LINE_MAX", _SC_LINE_MAX},
6358#endif
6359#ifdef _SC_LOGIN_NAME_MAX
6360 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6361#endif
6362#ifdef _SC_LOGNAME_MAX
6363 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6364#endif
6365#ifdef _SC_LONG_BIT
6366 {"SC_LONG_BIT", _SC_LONG_BIT},
6367#endif
Fred Draked86ed291999-12-15 15:34:33 +00006368#ifdef _SC_MAC
6369 {"SC_MAC", _SC_MAC},
6370#endif
Fred Drakec9680921999-12-13 16:37:25 +00006371#ifdef _SC_MAPPED_FILES
6372 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6373#endif
6374#ifdef _SC_MAXPID
6375 {"SC_MAXPID", _SC_MAXPID},
6376#endif
6377#ifdef _SC_MB_LEN_MAX
6378 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6379#endif
6380#ifdef _SC_MEMLOCK
6381 {"SC_MEMLOCK", _SC_MEMLOCK},
6382#endif
6383#ifdef _SC_MEMLOCK_RANGE
6384 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6385#endif
6386#ifdef _SC_MEMORY_PROTECTION
6387 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6388#endif
6389#ifdef _SC_MESSAGE_PASSING
6390 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6391#endif
Fred Draked86ed291999-12-15 15:34:33 +00006392#ifdef _SC_MMAP_FIXED_ALIGNMENT
6393 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6394#endif
Fred Drakec9680921999-12-13 16:37:25 +00006395#ifdef _SC_MQ_OPEN_MAX
6396 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6397#endif
6398#ifdef _SC_MQ_PRIO_MAX
6399 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6400#endif
Fred Draked86ed291999-12-15 15:34:33 +00006401#ifdef _SC_NACLS_MAX
6402 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6403#endif
Fred Drakec9680921999-12-13 16:37:25 +00006404#ifdef _SC_NGROUPS_MAX
6405 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6406#endif
6407#ifdef _SC_NL_ARGMAX
6408 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6409#endif
6410#ifdef _SC_NL_LANGMAX
6411 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6412#endif
6413#ifdef _SC_NL_MSGMAX
6414 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6415#endif
6416#ifdef _SC_NL_NMAX
6417 {"SC_NL_NMAX", _SC_NL_NMAX},
6418#endif
6419#ifdef _SC_NL_SETMAX
6420 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6421#endif
6422#ifdef _SC_NL_TEXTMAX
6423 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6424#endif
6425#ifdef _SC_NPROCESSORS_CONF
6426 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6427#endif
6428#ifdef _SC_NPROCESSORS_ONLN
6429 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6430#endif
Fred Draked86ed291999-12-15 15:34:33 +00006431#ifdef _SC_NPROC_CONF
6432 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6433#endif
6434#ifdef _SC_NPROC_ONLN
6435 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6436#endif
Fred Drakec9680921999-12-13 16:37:25 +00006437#ifdef _SC_NZERO
6438 {"SC_NZERO", _SC_NZERO},
6439#endif
6440#ifdef _SC_OPEN_MAX
6441 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6442#endif
6443#ifdef _SC_PAGESIZE
6444 {"SC_PAGESIZE", _SC_PAGESIZE},
6445#endif
6446#ifdef _SC_PAGE_SIZE
6447 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6448#endif
6449#ifdef _SC_PASS_MAX
6450 {"SC_PASS_MAX", _SC_PASS_MAX},
6451#endif
6452#ifdef _SC_PHYS_PAGES
6453 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6454#endif
6455#ifdef _SC_PII
6456 {"SC_PII", _SC_PII},
6457#endif
6458#ifdef _SC_PII_INTERNET
6459 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6460#endif
6461#ifdef _SC_PII_INTERNET_DGRAM
6462 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6463#endif
6464#ifdef _SC_PII_INTERNET_STREAM
6465 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6466#endif
6467#ifdef _SC_PII_OSI
6468 {"SC_PII_OSI", _SC_PII_OSI},
6469#endif
6470#ifdef _SC_PII_OSI_CLTS
6471 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6472#endif
6473#ifdef _SC_PII_OSI_COTS
6474 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6475#endif
6476#ifdef _SC_PII_OSI_M
6477 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6478#endif
6479#ifdef _SC_PII_SOCKET
6480 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6481#endif
6482#ifdef _SC_PII_XTI
6483 {"SC_PII_XTI", _SC_PII_XTI},
6484#endif
6485#ifdef _SC_POLL
6486 {"SC_POLL", _SC_POLL},
6487#endif
6488#ifdef _SC_PRIORITIZED_IO
6489 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6490#endif
6491#ifdef _SC_PRIORITY_SCHEDULING
6492 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6493#endif
6494#ifdef _SC_REALTIME_SIGNALS
6495 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6496#endif
6497#ifdef _SC_RE_DUP_MAX
6498 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6499#endif
6500#ifdef _SC_RTSIG_MAX
6501 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6502#endif
6503#ifdef _SC_SAVED_IDS
6504 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6505#endif
6506#ifdef _SC_SCHAR_MAX
6507 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6508#endif
6509#ifdef _SC_SCHAR_MIN
6510 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6511#endif
6512#ifdef _SC_SELECT
6513 {"SC_SELECT", _SC_SELECT},
6514#endif
6515#ifdef _SC_SEMAPHORES
6516 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6517#endif
6518#ifdef _SC_SEM_NSEMS_MAX
6519 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6520#endif
6521#ifdef _SC_SEM_VALUE_MAX
6522 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6523#endif
6524#ifdef _SC_SHARED_MEMORY_OBJECTS
6525 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6526#endif
6527#ifdef _SC_SHRT_MAX
6528 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6529#endif
6530#ifdef _SC_SHRT_MIN
6531 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6532#endif
6533#ifdef _SC_SIGQUEUE_MAX
6534 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6535#endif
6536#ifdef _SC_SIGRT_MAX
6537 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6538#endif
6539#ifdef _SC_SIGRT_MIN
6540 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6541#endif
Fred Draked86ed291999-12-15 15:34:33 +00006542#ifdef _SC_SOFTPOWER
6543 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6544#endif
Fred Drakec9680921999-12-13 16:37:25 +00006545#ifdef _SC_SPLIT_CACHE
6546 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6547#endif
6548#ifdef _SC_SSIZE_MAX
6549 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6550#endif
6551#ifdef _SC_STACK_PROT
6552 {"SC_STACK_PROT", _SC_STACK_PROT},
6553#endif
6554#ifdef _SC_STREAM_MAX
6555 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6556#endif
6557#ifdef _SC_SYNCHRONIZED_IO
6558 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6559#endif
6560#ifdef _SC_THREADS
6561 {"SC_THREADS", _SC_THREADS},
6562#endif
6563#ifdef _SC_THREAD_ATTR_STACKADDR
6564 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6565#endif
6566#ifdef _SC_THREAD_ATTR_STACKSIZE
6567 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6568#endif
6569#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6570 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6571#endif
6572#ifdef _SC_THREAD_KEYS_MAX
6573 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6574#endif
6575#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6576 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6577#endif
6578#ifdef _SC_THREAD_PRIO_INHERIT
6579 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6580#endif
6581#ifdef _SC_THREAD_PRIO_PROTECT
6582 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6583#endif
6584#ifdef _SC_THREAD_PROCESS_SHARED
6585 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6586#endif
6587#ifdef _SC_THREAD_SAFE_FUNCTIONS
6588 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6589#endif
6590#ifdef _SC_THREAD_STACK_MIN
6591 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6592#endif
6593#ifdef _SC_THREAD_THREADS_MAX
6594 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6595#endif
6596#ifdef _SC_TIMERS
6597 {"SC_TIMERS", _SC_TIMERS},
6598#endif
6599#ifdef _SC_TIMER_MAX
6600 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6601#endif
6602#ifdef _SC_TTY_NAME_MAX
6603 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6604#endif
6605#ifdef _SC_TZNAME_MAX
6606 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6607#endif
6608#ifdef _SC_T_IOV_MAX
6609 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6610#endif
6611#ifdef _SC_UCHAR_MAX
6612 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6613#endif
6614#ifdef _SC_UINT_MAX
6615 {"SC_UINT_MAX", _SC_UINT_MAX},
6616#endif
6617#ifdef _SC_UIO_MAXIOV
6618 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6619#endif
6620#ifdef _SC_ULONG_MAX
6621 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6622#endif
6623#ifdef _SC_USHRT_MAX
6624 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6625#endif
6626#ifdef _SC_VERSION
6627 {"SC_VERSION", _SC_VERSION},
6628#endif
6629#ifdef _SC_WORD_BIT
6630 {"SC_WORD_BIT", _SC_WORD_BIT},
6631#endif
6632#ifdef _SC_XBS5_ILP32_OFF32
6633 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6634#endif
6635#ifdef _SC_XBS5_ILP32_OFFBIG
6636 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6637#endif
6638#ifdef _SC_XBS5_LP64_OFF64
6639 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6640#endif
6641#ifdef _SC_XBS5_LPBIG_OFFBIG
6642 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6643#endif
6644#ifdef _SC_XOPEN_CRYPT
6645 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6646#endif
6647#ifdef _SC_XOPEN_ENH_I18N
6648 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6649#endif
6650#ifdef _SC_XOPEN_LEGACY
6651 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6652#endif
6653#ifdef _SC_XOPEN_REALTIME
6654 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6655#endif
6656#ifdef _SC_XOPEN_REALTIME_THREADS
6657 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6658#endif
6659#ifdef _SC_XOPEN_SHM
6660 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6661#endif
6662#ifdef _SC_XOPEN_UNIX
6663 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6664#endif
6665#ifdef _SC_XOPEN_VERSION
6666 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6667#endif
6668#ifdef _SC_XOPEN_XCU_VERSION
6669 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6670#endif
6671#ifdef _SC_XOPEN_XPG2
6672 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6673#endif
6674#ifdef _SC_XOPEN_XPG3
6675 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6676#endif
6677#ifdef _SC_XOPEN_XPG4
6678 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6679#endif
6680};
6681
6682static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006683conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006684{
6685 return conv_confname(arg, valuep, posix_constants_sysconf,
6686 sizeof(posix_constants_sysconf)
6687 / sizeof(struct constdef));
6688}
6689
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006690PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006691"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006692Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006693
6694static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006695posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006696{
6697 PyObject *result = NULL;
6698 int name;
6699
6700 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6701 int value;
6702
6703 errno = 0;
6704 value = sysconf(name);
6705 if (value == -1 && errno != 0)
6706 posix_error();
6707 else
6708 result = PyInt_FromLong(value);
6709 }
6710 return result;
6711}
6712#endif
6713
6714
Fred Drakebec628d1999-12-15 18:31:10 +00006715/* This code is used to ensure that the tables of configuration value names
6716 * are in sorted order as required by conv_confname(), and also to build the
6717 * the exported dictionaries that are used to publish information about the
6718 * names available on the host platform.
6719 *
6720 * Sorting the table at runtime ensures that the table is properly ordered
6721 * when used, even for platforms we're not able to test on. It also makes
6722 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006723 */
Fred Drakebec628d1999-12-15 18:31:10 +00006724
6725static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006726cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006727{
6728 const struct constdef *c1 =
6729 (const struct constdef *) v1;
6730 const struct constdef *c2 =
6731 (const struct constdef *) v2;
6732
6733 return strcmp(c1->name, c2->name);
6734}
6735
6736static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006737setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006738 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006739{
Fred Drakebec628d1999-12-15 18:31:10 +00006740 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006741 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006742
6743 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6744 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006745 if (d == NULL)
6746 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006747
Barry Warsaw3155db32000-04-13 15:20:40 +00006748 for (i=0; i < tablesize; ++i) {
6749 PyObject *o = PyInt_FromLong(table[i].value);
6750 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6751 Py_XDECREF(o);
6752 Py_DECREF(d);
6753 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006754 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006755 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006756 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006757 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006758}
6759
Fred Drakebec628d1999-12-15 18:31:10 +00006760/* Return -1 on failure, 0 on success. */
6761static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006762setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006763{
6764#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006765 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006766 sizeof(posix_constants_pathconf)
6767 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006768 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006769 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006770#endif
6771#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006772 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006773 sizeof(posix_constants_confstr)
6774 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006775 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006776 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006777#endif
6778#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006779 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006780 sizeof(posix_constants_sysconf)
6781 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006782 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006783 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006784#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006785 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006786}
Fred Draked86ed291999-12-15 15:34:33 +00006787
6788
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006789PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006790"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006791Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006792in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006793
6794static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006795posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006796{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006797 abort();
6798 /*NOTREACHED*/
6799 Py_FatalError("abort() called from Python code didn't abort!");
6800 return NULL;
6801}
Fred Drakebec628d1999-12-15 18:31:10 +00006802
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006803#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006804PyDoc_STRVAR(win32_startfile__doc__,
6805"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006806\n\
6807This acts like double-clicking the file in Explorer, or giving the file\n\
6808name as an argument to the DOS \"start\" command: the file is opened\n\
6809with whatever application (if any) its extension is associated.\n\
6810\n\
6811startfile returns as soon as the associated application is launched.\n\
6812There is no option to wait for the application to close, and no way\n\
6813to retrieve the application's exit status.\n\
6814\n\
6815The filepath is relative to the current directory. If you want to use\n\
6816an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006817the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006818
6819static PyObject *
6820win32_startfile(PyObject *self, PyObject *args)
6821{
6822 char *filepath;
6823 HINSTANCE rc;
6824 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6825 return NULL;
6826 Py_BEGIN_ALLOW_THREADS
6827 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6828 Py_END_ALLOW_THREADS
6829 if (rc <= (HINSTANCE)32)
6830 return win32_error("startfile", filepath);
6831 Py_INCREF(Py_None);
6832 return Py_None;
6833}
6834#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006835
Martin v. Löwis438b5342002-12-27 10:16:42 +00006836#ifdef HAVE_GETLOADAVG
6837PyDoc_STRVAR(posix_getloadavg__doc__,
6838"getloadavg() -> (float, float, float)\n\n\
6839Return the number of processes in the system run queue averaged over\n\
6840the last 1, 5, and 15 minutes or raises OSError if the load average\n\
6841was unobtainable");
6842
6843static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006844posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00006845{
6846 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00006847 if (getloadavg(loadavg, 3)!=3) {
6848 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
6849 return NULL;
6850 } else
6851 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
6852}
6853#endif
6854
6855
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006856static PyMethodDef posix_methods[] = {
6857 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6858#ifdef HAVE_TTYNAME
6859 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6860#endif
6861 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6862 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006863#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006864 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006865#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00006866#ifdef HAVE_LCHOWN
6867 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
6868#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006869#ifdef HAVE_CHROOT
6870 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6871#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006872#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00006873 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006874#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006875#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00006876 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00006877#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00006878 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006879#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00006880#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006881#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006882 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006883#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006884 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6885 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6886 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006887#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006888 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006889#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006890#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006891 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006892#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006893 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6894 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6895 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00006896 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006897#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006898 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006899#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006900#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006901 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006902#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006903 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006904#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00006905 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006906#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006907 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6908 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6909 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006910#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00006911 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006912#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006913 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006914#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006915 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6916 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006917#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006918#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006919 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6920 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006921#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006922#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00006923 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006924#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006925#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00006926 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006927#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006928#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00006929 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006930#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006931#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00006932 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00006933#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006934#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00006935 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006936#endif /* HAVE_GETEGID */
6937#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00006938 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006939#endif /* HAVE_GETEUID */
6940#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00006941 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006942#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006943#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00006944 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00006945#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00006946 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006947#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00006948 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006949#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006950#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00006951 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006952#endif /* HAVE_GETPPID */
6953#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00006954 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006955#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006956#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00006957 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00006958#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006959#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006960 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006961#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006962#ifdef HAVE_KILLPG
6963 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6964#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006965#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006966 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006967#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006968#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006969 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006970#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006971 {"popen2", win32_popen2, METH_VARARGS},
6972 {"popen3", win32_popen3, METH_VARARGS},
6973 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00006974 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006975#else
6976#if defined(PYOS_OS2) && defined(PYCC_GCC)
6977 {"popen2", os2emx_popen2, METH_VARARGS},
6978 {"popen3", os2emx_popen3, METH_VARARGS},
6979 {"popen4", os2emx_popen4, METH_VARARGS},
6980#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006981#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006982#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006983#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006984 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006985#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006986#ifdef HAVE_SETEUID
6987 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6988#endif /* HAVE_SETEUID */
6989#ifdef HAVE_SETEGID
6990 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6991#endif /* HAVE_SETEGID */
6992#ifdef HAVE_SETREUID
6993 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6994#endif /* HAVE_SETREUID */
6995#ifdef HAVE_SETREGID
6996 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6997#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006998#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006999 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007000#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007001#ifdef HAVE_SETGROUPS
7002 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7003#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007004#ifdef HAVE_GETPGID
7005 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7006#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007007#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007008 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007009#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007010#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007011 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007012#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00007013#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007014 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007015#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007016#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007017 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007018#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007019#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007020 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007021#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007022#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007023 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007024#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007025#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007026 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007027#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007028 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7029 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7030 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7031 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7032 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7033 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7034 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7035 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7036 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007037 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007038#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007039 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007040#endif
7041#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007042 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007043#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007044#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007045 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7046#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007047#ifdef HAVE_DEVICE_MACROS
7048 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7049 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7050 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7051#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007052#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007053 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007054#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007055#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007056 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007057#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007058#ifdef HAVE_UNSETENV
7059 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7060#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007061#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007062 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007063#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007064#ifdef HAVE_FCHDIR
7065 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7066#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007067#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007068 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007069#endif
7070#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007071 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007072#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007073#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007074#ifdef WCOREDUMP
7075 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7076#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007077#ifdef WIFCONTINUED
7078 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7079#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007080#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007081 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007082#endif /* WIFSTOPPED */
7083#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007084 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007085#endif /* WIFSIGNALED */
7086#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007087 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007088#endif /* WIFEXITED */
7089#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007090 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007091#endif /* WEXITSTATUS */
7092#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007093 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007094#endif /* WTERMSIG */
7095#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007096 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007097#endif /* WSTOPSIG */
7098#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007099#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007100 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007101#endif
7102#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007103 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007104#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007105#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00007106 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007107#endif
7108#ifdef HAVE_TEMPNAM
7109 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7110#endif
7111#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00007112 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007113#endif
Fred Drakec9680921999-12-13 16:37:25 +00007114#ifdef HAVE_CONFSTR
7115 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7116#endif
7117#ifdef HAVE_SYSCONF
7118 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7119#endif
7120#ifdef HAVE_FPATHCONF
7121 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7122#endif
7123#ifdef HAVE_PATHCONF
7124 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7125#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007126 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007127#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007128 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7129#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007130#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007131 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007132#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007133 {NULL, NULL} /* Sentinel */
7134};
7135
7136
Barry Warsaw4a342091996-12-19 23:50:02 +00007137static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007138ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007139{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007140 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007141}
7142
Guido van Rossumd48f2521997-12-05 22:19:34 +00007143#if defined(PYOS_OS2)
7144/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007145static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007146{
7147 APIRET rc;
7148 ULONG values[QSV_MAX+1];
7149 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007150 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007151
7152 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007153 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007154 Py_END_ALLOW_THREADS
7155
7156 if (rc != NO_ERROR) {
7157 os2_error(rc);
7158 return -1;
7159 }
7160
Fred Drake4d1e64b2002-04-15 19:40:07 +00007161 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7162 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7163 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7164 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7165 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7166 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7167 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007168
7169 switch (values[QSV_VERSION_MINOR]) {
7170 case 0: ver = "2.00"; break;
7171 case 10: ver = "2.10"; break;
7172 case 11: ver = "2.11"; break;
7173 case 30: ver = "3.00"; break;
7174 case 40: ver = "4.00"; break;
7175 case 50: ver = "5.00"; break;
7176 default:
Tim Peters885d4572001-11-28 20:27:42 +00007177 PyOS_snprintf(tmp, sizeof(tmp),
7178 "%d-%d", values[QSV_VERSION_MAJOR],
7179 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007180 ver = &tmp[0];
7181 }
7182
7183 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007184 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007185 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007186
7187 /* Add Indicator of Which Drive was Used to Boot the System */
7188 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7189 tmp[1] = ':';
7190 tmp[2] = '\0';
7191
Fred Drake4d1e64b2002-04-15 19:40:07 +00007192 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007193}
7194#endif
7195
Barry Warsaw4a342091996-12-19 23:50:02 +00007196static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007197all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007198{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007199#ifdef F_OK
7200 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007201#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007202#ifdef R_OK
7203 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007204#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007205#ifdef W_OK
7206 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007207#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007208#ifdef X_OK
7209 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007210#endif
Fred Drakec9680921999-12-13 16:37:25 +00007211#ifdef NGROUPS_MAX
7212 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7213#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007214#ifdef TMP_MAX
7215 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7216#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007217#ifdef WCONTINUED
7218 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7219#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007220#ifdef WNOHANG
7221 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007222#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007223#ifdef WUNTRACED
7224 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7225#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007226#ifdef O_RDONLY
7227 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7228#endif
7229#ifdef O_WRONLY
7230 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7231#endif
7232#ifdef O_RDWR
7233 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7234#endif
7235#ifdef O_NDELAY
7236 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7237#endif
7238#ifdef O_NONBLOCK
7239 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7240#endif
7241#ifdef O_APPEND
7242 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7243#endif
7244#ifdef O_DSYNC
7245 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7246#endif
7247#ifdef O_RSYNC
7248 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7249#endif
7250#ifdef O_SYNC
7251 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7252#endif
7253#ifdef O_NOCTTY
7254 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7255#endif
7256#ifdef O_CREAT
7257 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7258#endif
7259#ifdef O_EXCL
7260 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7261#endif
7262#ifdef O_TRUNC
7263 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7264#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007265#ifdef O_BINARY
7266 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7267#endif
7268#ifdef O_TEXT
7269 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7270#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007271#ifdef O_LARGEFILE
7272 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7273#endif
7274
Tim Peters5aa91602002-01-30 05:46:57 +00007275/* MS Windows */
7276#ifdef O_NOINHERIT
7277 /* Don't inherit in child processes. */
7278 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7279#endif
7280#ifdef _O_SHORT_LIVED
7281 /* Optimize for short life (keep in memory). */
7282 /* MS forgot to define this one with a non-underscore form too. */
7283 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7284#endif
7285#ifdef O_TEMPORARY
7286 /* Automatically delete when last handle is closed. */
7287 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7288#endif
7289#ifdef O_RANDOM
7290 /* Optimize for random access. */
7291 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7292#endif
7293#ifdef O_SEQUENTIAL
7294 /* Optimize for sequential access. */
7295 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7296#endif
7297
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007298/* GNU extensions. */
7299#ifdef O_DIRECT
7300 /* Direct disk access. */
7301 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7302#endif
7303#ifdef O_DIRECTORY
7304 /* Must be a directory. */
7305 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7306#endif
7307#ifdef O_NOFOLLOW
7308 /* Do not follow links. */
7309 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7310#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007311
Barry Warsaw5676bd12003-01-07 20:57:09 +00007312 /* These come from sysexits.h */
7313#ifdef EX_OK
7314 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007315#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007316#ifdef EX_USAGE
7317 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007318#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007319#ifdef EX_DATAERR
7320 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007321#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007322#ifdef EX_NOINPUT
7323 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007324#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007325#ifdef EX_NOUSER
7326 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007327#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007328#ifdef EX_NOHOST
7329 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007330#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007331#ifdef EX_UNAVAILABLE
7332 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007333#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007334#ifdef EX_SOFTWARE
7335 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007336#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007337#ifdef EX_OSERR
7338 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007339#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007340#ifdef EX_OSFILE
7341 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007342#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007343#ifdef EX_CANTCREAT
7344 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007345#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007346#ifdef EX_IOERR
7347 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007348#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007349#ifdef EX_TEMPFAIL
7350 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007351#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007352#ifdef EX_PROTOCOL
7353 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007354#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007355#ifdef EX_NOPERM
7356 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007357#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007358#ifdef EX_CONFIG
7359 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007360#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007361#ifdef EX_NOTFOUND
7362 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007363#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007364
Guido van Rossum246bc171999-02-01 23:54:31 +00007365#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007366#if defined(PYOS_OS2) && defined(PYCC_GCC)
7367 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7368 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7369 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7370 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7371 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7372 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7373 if (ins(d, "P_PM", (long)P_PM)) return -1;
7374 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7375 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7376 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7377 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7378 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7379 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7380 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7381 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7382 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7383 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7384 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7385 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7386 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7387#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007388 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7389 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7390 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7391 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7392 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007393#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007394#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007395
Guido van Rossumd48f2521997-12-05 22:19:34 +00007396#if defined(PYOS_OS2)
7397 if (insertvalues(d)) return -1;
7398#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007399 return 0;
7400}
7401
7402
Tim Peters5aa91602002-01-30 05:46:57 +00007403#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007404#define INITFUNC initnt
7405#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007406
7407#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007408#define INITFUNC initos2
7409#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007410
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007411#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007412#define INITFUNC initposix
7413#define MODNAME "posix"
7414#endif
7415
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007416PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007417INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007418{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007419 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007420
Fred Drake4d1e64b2002-04-15 19:40:07 +00007421 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007422 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007423 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00007424
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007425 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007426 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007427 Py_XINCREF(v);
7428 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007429 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007430 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007431
Fred Drake4d1e64b2002-04-15 19:40:07 +00007432 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007433 return;
7434
Fred Drake4d1e64b2002-04-15 19:40:07 +00007435 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007436 return;
7437
Fred Drake4d1e64b2002-04-15 19:40:07 +00007438 Py_INCREF(PyExc_OSError);
7439 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007440
Guido van Rossumb3d39562000-01-31 18:41:26 +00007441#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007442 if (posix_putenv_garbage == NULL)
7443 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007444#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007445
Guido van Rossum14648392001-12-08 18:02:58 +00007446 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007447 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7448 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7449 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007450 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007451 structseq_new = StatResultType.tp_new;
7452 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00007453 Py_INCREF((PyObject*) &StatResultType);
7454 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007455
Guido van Rossum14648392001-12-08 18:02:58 +00007456 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007457 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007458 Py_INCREF((PyObject*) &StatVFSResultType);
7459 PyModule_AddObject(m, "statvfs_result",
7460 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00007461}