blob: fd7f69f6b1f2debb76d99f7e658c7b23e484242b [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
19PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000020"This module provides access to operating system functionality that is\n\
21standardized by the C Standard and the POSIX standard (a thinly\n\
22disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000023corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000024
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000025#ifndef Py_USING_UNICODE
26/* This is used in signatures of functions. */
27#define Py_UNICODE void
28#endif
29
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000030#if defined(PYOS_OS2)
31#define INCL_DOS
32#define INCL_DOSERRORS
33#define INCL_DOSPROCESS
34#define INCL_NOPMAPI
35#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000036#if defined(PYCC_GCC)
37#include <ctype.h>
38#include <io.h>
39#include <stdio.h>
40#include <process.h>
41#include "osdefs.h"
42#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000043#endif
44
Guido van Rossumb6775db1994-08-01 11:34:53 +000045#include <sys/types.h>
46#include <sys/stat.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +000047
Guido van Rossum36bc6801995-06-14 22:54:23 +000048#ifdef HAVE_SYS_WAIT_H
49#include <sys/wait.h> /* For WNOHANG */
50#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000051
Guido van Rossuma376cc51996-12-05 23:43:35 +000052#ifdef HAVE_SIGNAL_H
53#include <signal.h>
54#endif
55
Guido van Rossumb6775db1994-08-01 11:34:53 +000056#ifdef HAVE_FCNTL_H
57#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000058#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000059
Guido van Rossuma6535fd2001-10-18 19:44:10 +000060#ifdef HAVE_GRP_H
61#include <grp.h>
62#endif
63
Guido van Rossuma4916fa1996-05-23 22:58:55 +000064/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000065/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000066#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000067#include <process.h>
68#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000069#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000070#define HAVE_GETCWD 1
71#define HAVE_OPENDIR 1
72#define HAVE_SYSTEM 1
73#if defined(__OS2__)
74#define HAVE_EXECV 1
75#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000076#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000077#include <process.h>
78#else
79#ifdef __BORLANDC__ /* Borland compiler */
80#define HAVE_EXECV 1
81#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000082#define HAVE_OPENDIR 1
83#define HAVE_PIPE 1
84#define HAVE_POPEN 1
85#define HAVE_SYSTEM 1
86#define HAVE_WAIT 1
87#else
88#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000089#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +000090#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000091#define HAVE_EXECV 1
92#define HAVE_PIPE 1
93#define HAVE_POPEN 1
94#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +000095#define HAVE_CWAIT 1
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000096#else
97#if defined(PYOS_OS2) && defined(PYCC_GCC)
98/* Everything needed is defined in PC/os2emx/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000099#else /* all other compilers */
100/* Unix functions that the configure script doesn't check for */
101#define HAVE_EXECV 1
102#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000103#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
104#define HAVE_FORK1 1
105#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000106#define HAVE_GETCWD 1
107#define HAVE_GETEGID 1
108#define HAVE_GETEUID 1
109#define HAVE_GETGID 1
110#define HAVE_GETPPID 1
111#define HAVE_GETUID 1
112#define HAVE_KILL 1
113#define HAVE_OPENDIR 1
114#define HAVE_PIPE 1
115#define HAVE_POPEN 1
116#define HAVE_SYSTEM 1
117#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000118#define HAVE_TTYNAME 1
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000119#endif /* PYOS_OS2 && PYCC_GCC */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000120#endif /* _MSC_VER */
121#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000122#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000123#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000124
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000125#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000126
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000127#if defined(sun) && !defined(__SVR4)
128/* SunOS 4.1.4 doesn't have prototypes for these: */
129extern int rename(const char *, const char *);
130extern int pclose(FILE *);
131extern int fclose(FILE *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000132extern int fsync(int);
133extern int lstat(const char *, struct stat *);
134extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000135#endif
136
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000137#if defined(__sgi)&&_COMPILER_VERSION>=700
138/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
139 (default) */
140extern char *ctermid_r(char *);
141#endif
142
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000143#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000144#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000145extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000146#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000147#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000148extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000149#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000150extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000151#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000152#endif
153#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000154extern int chdir(char *);
155extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000156#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000157extern int chdir(const char *);
158extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000159#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000160#ifdef __BORLANDC__
161extern int chmod(const char *, int);
162#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000163extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000164#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000165extern int chown(const char *, uid_t, gid_t);
166extern char *getcwd(char *, int);
167extern char *strerror(int);
168extern int link(const char *, const char *);
169extern int rename(const char *, const char *);
170extern int stat(const char *, struct stat *);
171extern int unlink(const char *);
172extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000173#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000174extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000175#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000176#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000177extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000178#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000179#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000180
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000181#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000182
Guido van Rossumb6775db1994-08-01 11:34:53 +0000183#ifdef HAVE_UTIME_H
184#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000185#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000186
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000187#ifdef HAVE_SYS_UTIME_H
188#include <sys/utime.h>
189#define HAVE_UTIME_H /* pretend we do for the rest of this file */
190#endif /* HAVE_SYS_UTIME_H */
191
Guido van Rossumb6775db1994-08-01 11:34:53 +0000192#ifdef HAVE_SYS_TIMES_H
193#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000194#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000195
196#ifdef HAVE_SYS_PARAM_H
197#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000198#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000199
200#ifdef HAVE_SYS_UTSNAME_H
201#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000202#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000203
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000204#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000206#define NAMLEN(dirent) strlen((dirent)->d_name)
207#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000208#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000209#include <direct.h>
210#define NAMLEN(dirent) strlen((dirent)->d_name)
211#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000212#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000213#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000214#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000215#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000216#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000217#endif
218#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000219#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000220#endif
221#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000222#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000223#endif
224#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000225
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000226#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000227#include <direct.h>
228#include <io.h>
229#include <process.h>
Tim Petersbc2e10e2002-03-03 23:17:02 +0000230#include "osdefs.h"
Tim Petersee66d0c2002-07-15 16:10:55 +0000231#define WIN32_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000233#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000234#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000235#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000236#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000237
Guido van Rossumd48f2521997-12-05 22:19:34 +0000238#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000239#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000240#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000241
Tim Petersbc2e10e2002-03-03 23:17:02 +0000242#ifndef MAXPATHLEN
243#define MAXPATHLEN 1024
244#endif /* MAXPATHLEN */
245
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000246#ifdef UNION_WAIT
247/* Emulate some macros on systems that have a union instead of macros */
248
249#ifndef WIFEXITED
250#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
251#endif
252
253#ifndef WEXITSTATUS
254#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
255#endif
256
257#ifndef WTERMSIG
258#define WTERMSIG(u_wait) ((u_wait).w_termsig)
259#endif
260
261#endif /* UNION_WAIT */
262
Greg Wardb48bc172000-03-01 21:51:56 +0000263/* Don't use the "_r" form if we don't need it (also, won't have a
264 prototype for it, at least on Solaris -- maybe others as well?). */
265#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
266#define USE_CTERMID_R
267#endif
268
269#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
270#define USE_TMPNAM_R
271#endif
272
Fred Drake699f3522000-06-29 21:12:41 +0000273/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000274#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000275#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +0000276# define STAT _stati64
277# define FSTAT _fstati64
278# define STRUCT_STAT struct _stati64
279#else
280# define STAT stat
281# define FSTAT fstat
282# define STRUCT_STAT struct stat
283#endif
284
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000285#if defined(MAJOR_IN_MKDEV)
286#include <sys/mkdev.h>
287#else
288#if defined(MAJOR_IN_SYSMACROS)
289#include <sys/sysmacros.h>
290#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000291#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
292#include <sys/mkdev.h>
293#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000294#endif
Fred Drake699f3522000-06-29 21:12:41 +0000295
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000296/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000297#ifdef WITH_NEXT_FRAMEWORK
298/* On Darwin/MacOSX a shared library or framework has no access to
299** environ directly, we must obtain it with _NSGetEnviron().
300*/
301#include <crt_externs.h>
302static char **environ;
303#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000304extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000305#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000306
Barry Warsaw53699e91996-12-10 23:23:01 +0000307static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000308convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000309{
Barry Warsaw53699e91996-12-10 23:23:01 +0000310 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000311 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000312 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000313 if (d == NULL)
314 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000315#ifdef WITH_NEXT_FRAMEWORK
316 if (environ == NULL)
317 environ = *_NSGetEnviron();
318#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000319 if (environ == NULL)
320 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000321 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000322 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000323 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000324 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000325 char *p = strchr(*e, '=');
326 if (p == NULL)
327 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000328 k = PyString_FromStringAndSize(*e, (int)(p-*e));
329 if (k == NULL) {
330 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000331 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000332 }
333 v = PyString_FromString(p+1);
334 if (v == NULL) {
335 PyErr_Clear();
336 Py_DECREF(k);
337 continue;
338 }
339 if (PyDict_GetItem(d, k) == NULL) {
340 if (PyDict_SetItem(d, k, v) != 0)
341 PyErr_Clear();
342 }
343 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000344 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000345 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000346#if defined(PYOS_OS2)
347 {
348 APIRET rc;
349 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
350
351 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000352 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000353 PyObject *v = PyString_FromString(buffer);
354 PyDict_SetItemString(d, "BEGINLIBPATH", v);
355 Py_DECREF(v);
356 }
357 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
358 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
359 PyObject *v = PyString_FromString(buffer);
360 PyDict_SetItemString(d, "ENDLIBPATH", v);
361 Py_DECREF(v);
362 }
363 }
364#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000365 return d;
366}
367
368
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000369/* Set a POSIX-specific error from errno, and return NULL */
370
Barry Warsawd58d7641998-07-23 16:14:40 +0000371static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000372posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000373{
Barry Warsawca74da41999-02-09 19:31:45 +0000374 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000375}
Barry Warsawd58d7641998-07-23 16:14:40 +0000376static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000377posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000378{
Barry Warsawca74da41999-02-09 19:31:45 +0000379 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000380}
381
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000382#ifdef Py_WIN_WIDE_FILENAMES
383static PyObject *
384posix_error_with_unicode_filename(Py_UNICODE* name)
385{
386 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
387}
388#endif /* Py_WIN_WIDE_FILENAMES */
389
390
Mark Hammondef8b6542001-05-13 08:04:26 +0000391static PyObject *
392posix_error_with_allocated_filename(char* name)
393{
394 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
395 PyMem_Free(name);
396 return rc;
397}
398
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000399#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000400static PyObject *
401win32_error(char* function, char* filename)
402{
Mark Hammond33a6da92000-08-15 00:46:38 +0000403 /* XXX We should pass the function name along in the future.
404 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000405 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000406 Windows error object, which is non-trivial.
407 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000408 errno = GetLastError();
409 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000410 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000411 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000412 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000413}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000414
415#ifdef Py_WIN_WIDE_FILENAMES
416static PyObject *
417win32_error_unicode(char* function, Py_UNICODE* filename)
418{
419 /* XXX - see win32_error for comments on 'function' */
420 errno = GetLastError();
421 if (filename)
422 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
423 else
424 return PyErr_SetFromWindowsErr(errno);
425}
426
427static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
428{
429 /* XXX Perhaps we should make this API an alias of
430 PyObject_Unicode() instead ?! */
431 if (PyUnicode_CheckExact(obj)) {
432 Py_INCREF(obj);
433 return obj;
434 }
435 if (PyUnicode_Check(obj)) {
436 /* For a Unicode subtype that's not a Unicode object,
437 return a true Unicode object with the same data. */
438 return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),
439 PyUnicode_GET_SIZE(obj));
440 }
441 return PyUnicode_FromEncodedObject(obj,
442 Py_FileSystemDefaultEncoding,
443 "strict");
444}
445
446#endif /* Py_WIN_WIDE_FILENAMES */
447
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000448#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000449
Guido van Rossumd48f2521997-12-05 22:19:34 +0000450#if defined(PYOS_OS2)
451/**********************************************************************
452 * Helper Function to Trim and Format OS/2 Messages
453 **********************************************************************/
454 static void
455os2_formatmsg(char *msgbuf, int msglen, char *reason)
456{
457 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
458
459 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
460 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
461
462 while (lastc > msgbuf && isspace(*lastc))
463 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
464 }
465
466 /* Add Optional Reason Text */
467 if (reason) {
468 strcat(msgbuf, " : ");
469 strcat(msgbuf, reason);
470 }
471}
472
473/**********************************************************************
474 * Decode an OS/2 Operating System Error Code
475 *
476 * A convenience function to lookup an OS/2 error code and return a
477 * text message we can use to raise a Python exception.
478 *
479 * Notes:
480 * The messages for errors returned from the OS/2 kernel reside in
481 * the file OSO001.MSG in the \OS2 directory hierarchy.
482 *
483 **********************************************************************/
484 static char *
485os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
486{
487 APIRET rc;
488 ULONG msglen;
489
490 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
491 Py_BEGIN_ALLOW_THREADS
492 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
493 errorcode, "oso001.msg", &msglen);
494 Py_END_ALLOW_THREADS
495
496 if (rc == NO_ERROR)
497 os2_formatmsg(msgbuf, msglen, reason);
498 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000499 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000500 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000501
502 return msgbuf;
503}
504
505/* Set an OS/2-specific error and return NULL. OS/2 kernel
506 errors are not in a global variable e.g. 'errno' nor are
507 they congruent with posix error numbers. */
508
509static PyObject * os2_error(int code)
510{
511 char text[1024];
512 PyObject *v;
513
514 os2_strerror(text, sizeof(text), code, "");
515
516 v = Py_BuildValue("(is)", code, text);
517 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000518 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000519 Py_DECREF(v);
520 }
521 return NULL; /* Signal to Python that an Exception is Pending */
522}
523
524#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000525
526/* POSIX generic methods */
527
Barry Warsaw53699e91996-12-10 23:23:01 +0000528static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000529posix_fildes(PyObject *fdobj, int (*func)(int))
530{
531 int fd;
532 int res;
533 fd = PyObject_AsFileDescriptor(fdobj);
534 if (fd < 0)
535 return NULL;
536 Py_BEGIN_ALLOW_THREADS
537 res = (*func)(fd);
538 Py_END_ALLOW_THREADS
539 if (res < 0)
540 return posix_error();
541 Py_INCREF(Py_None);
542 return Py_None;
543}
Guido van Rossum21142a01999-01-08 21:05:37 +0000544
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000545#ifdef Py_WIN_WIDE_FILENAMES
546static int
547unicode_file_names(void)
548{
549 static int canusewide = -1;
550 if (canusewide == -1) {
551 /* As per doc for ::GetVersion(), this is the correct test for
552 the Windows NT family. */
553 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
554 }
555 return canusewide;
556}
557#endif
558
Guido van Rossum21142a01999-01-08 21:05:37 +0000559static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000560posix_1str(PyObject *args, char *format, int (*func)(const char*),
561 char *wformat, int (*wfunc)(const Py_UNICODE*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000562{
Mark Hammondef8b6542001-05-13 08:04:26 +0000563 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000564 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000565#ifdef Py_WIN_WIDE_FILENAMES
566 if (unicode_file_names()) {
567 PyUnicodeObject *po;
568 if (PyArg_ParseTuple(args, wformat, &po)) {
569 Py_BEGIN_ALLOW_THREADS
570 /* PyUnicode_AS_UNICODE OK without thread
571 lock as it is a simple dereference. */
572 res = (*wfunc)(PyUnicode_AS_UNICODE(po));
573 Py_END_ALLOW_THREADS
574 if (res < 0)
Mark Hammondd3890362002-10-03 07:24:48 +0000575 return posix_error_with_unicode_filename(PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000576 Py_INCREF(Py_None);
577 return Py_None;
578 }
579 /* Drop the argument parsing error as narrow
580 strings are also valid. */
581 PyErr_Clear();
582 }
583#else
584 /* Platforms that don't support Unicode filenames
585 shouldn't be passing these extra params */
586 assert(wformat==NULL && wfunc == NULL);
587#endif
588
Tim Peters5aa91602002-01-30 05:46:57 +0000589 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000590 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000591 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000592 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000593 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000594 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000595 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000596 return posix_error_with_allocated_filename(path1);
597 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000598 Py_INCREF(Py_None);
599 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000600}
601
Barry Warsaw53699e91996-12-10 23:23:01 +0000602static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000603posix_2str(PyObject *args,
604 char *format,
605 int (*func)(const char *, const char *),
606 char *wformat,
607 int (*wfunc)(const Py_UNICODE *, const Py_UNICODE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000608{
Mark Hammondef8b6542001-05-13 08:04:26 +0000609 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000610 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000611#ifdef Py_WIN_WIDE_FILENAMES
612 if (unicode_file_names()) {
613 PyObject *po1;
614 PyObject *po2;
615 if (PyArg_ParseTuple(args, wformat, &po1, &po2)) {
616 if (PyUnicode_Check(po1) || PyUnicode_Check(po2)) {
617 PyObject *wpath1;
618 PyObject *wpath2;
619 wpath1 = _PyUnicode_FromFileSystemEncodedObject(po1);
620 wpath2 = _PyUnicode_FromFileSystemEncodedObject(po2);
621 if (!wpath1 || !wpath2) {
622 Py_XDECREF(wpath1);
623 Py_XDECREF(wpath2);
624 return NULL;
625 }
626 Py_BEGIN_ALLOW_THREADS
627 /* PyUnicode_AS_UNICODE OK without thread
628 lock as it is a simple dereference. */
629 res = (*wfunc)(PyUnicode_AS_UNICODE(wpath1),
630 PyUnicode_AS_UNICODE(wpath2));
631 Py_END_ALLOW_THREADS
632 Py_XDECREF(wpath1);
633 Py_XDECREF(wpath2);
634 if (res != 0)
635 return posix_error();
636 Py_INCREF(Py_None);
637 return Py_None;
638 }
639 /* Else flow through as neither is Unicode. */
640 }
641 /* Drop the argument parsing error as narrow
642 strings are also valid. */
643 PyErr_Clear();
644 }
645#else
646 /* Platforms that don't support Unicode filenames
647 shouldn't be passing these extra params */
648 assert(wformat==NULL && wfunc == NULL);
649#endif
650
Mark Hammondef8b6542001-05-13 08:04:26 +0000651 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000652 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000653 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000654 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000655 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000656 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000657 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000658 PyMem_Free(path1);
659 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000660 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000661 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000662 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000663 Py_INCREF(Py_None);
664 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000665}
666
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000667PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000668"stat_result: Result from stat or lstat.\n\n\
669This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000670 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000671or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
672\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000673Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000674they are available as attributes only.\n\
675\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000676See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000677
678static PyStructSequence_Field stat_result_fields[] = {
679 {"st_mode", "protection bits"},
680 {"st_ino", "inode"},
681 {"st_dev", "device"},
682 {"st_nlink", "number of hard links"},
683 {"st_uid", "user ID of owner"},
684 {"st_gid", "group ID of owner"},
685 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000686 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
687 {NULL, "integer time of last access"},
688 {NULL, "integer time of last modification"},
689 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000690 {"st_atime", "time of last access"},
691 {"st_mtime", "time of last modification"},
692 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000693#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000694 {"st_blksize", "blocksize for filesystem I/O"},
695#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000696#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000697 {"st_blocks", "number of blocks allocated"},
698#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000699#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000700 {"st_rdev", "device type (if inode device)"},
701#endif
702 {0}
703};
704
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000705#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000706#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000707#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000708#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000709#endif
710
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000711#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000712#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
713#else
714#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
715#endif
716
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000717#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000718#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
719#else
720#define ST_RDEV_IDX ST_BLOCKS_IDX
721#endif
722
723static PyStructSequence_Desc stat_result_desc = {
724 "stat_result", /* name */
725 stat_result__doc__, /* doc */
726 stat_result_fields,
727 10
728};
729
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000730PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000731"statvfs_result: Result from statvfs or fstatvfs.\n\n\
732This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000733 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000734or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000735\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000736See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000737
738static PyStructSequence_Field statvfs_result_fields[] = {
739 {"f_bsize", },
740 {"f_frsize", },
741 {"f_blocks", },
742 {"f_bfree", },
743 {"f_bavail", },
744 {"f_files", },
745 {"f_ffree", },
746 {"f_favail", },
747 {"f_flag", },
748 {"f_namemax",},
749 {0}
750};
751
752static PyStructSequence_Desc statvfs_result_desc = {
753 "statvfs_result", /* name */
754 statvfs_result__doc__, /* doc */
755 statvfs_result_fields,
756 10
757};
758
759static PyTypeObject StatResultType;
760static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000761static newfunc structseq_new;
762
763static PyObject *
764statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
765{
766 PyStructSequence *result;
767 int i;
768
769 result = (PyStructSequence*)structseq_new(type, args, kwds);
770 if (!result)
771 return NULL;
772 /* If we have been initialized from a tuple,
773 st_?time might be set to None. Initialize it
774 from the int slots. */
775 for (i = 7; i <= 9; i++) {
776 if (result->ob_item[i+3] == Py_None) {
777 Py_DECREF(Py_None);
778 Py_INCREF(result->ob_item[i]);
779 result->ob_item[i+3] = result->ob_item[i];
780 }
781 }
782 return (PyObject*)result;
783}
784
785
786
787/* If true, st_?time is float. */
788static int _stat_float_times = 0;
789
790PyDoc_STRVAR(stat_float_times__doc__,
791"stat_float_times([newval]) -> oldval\n\n\
792Determine whether os.[lf]stat represents time stamps as float objects.\n\
793If newval is True, future calls to stat() return floats, if it is False,\n\
794future calls return ints. \n\
795If newval is omitted, return the current setting.\n");
796
797static PyObject*
798stat_float_times(PyObject* self, PyObject *args)
799{
800 int newval = -1;
801 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
802 return NULL;
803 if (newval == -1)
804 /* Return old value */
805 return PyBool_FromLong(_stat_float_times);
806 _stat_float_times = newval;
807 Py_INCREF(Py_None);
808 return Py_None;
809}
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000810
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000811static void
812fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
813{
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000814 PyObject *fval,*ival;
815#if SIZEOF_TIME_T > SIZEOF_LONG
816 ival = PyLong_FromLongLong((LONG_LONG)sec);
817#else
818 ival = PyInt_FromLong((long)sec);
819#endif
820 if (_stat_float_times) {
821 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
822 } else {
823 fval = ival;
824 Py_INCREF(fval);
825 }
826 PyStructSequence_SET_ITEM(v, index, ival);
827 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000828}
829
Tim Peters5aa91602002-01-30 05:46:57 +0000830/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +0000831 (used by posix_stat() and posix_fstat()) */
832static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000833_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000834{
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000835 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000836 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000837 if (v == NULL)
838 return NULL;
839
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000840 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000841#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000842 PyStructSequence_SET_ITEM(v, 1,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000843 PyLong_FromLongLong((LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000844#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000845 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000846#endif
847#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +0000848 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000849 PyLong_FromLongLong((LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000850#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000851 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000852#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000853 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
854 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
855 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000856#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000857 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000858 PyLong_FromLongLong((LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000859#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000860 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000861#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000862
863#ifdef HAVE_STAT_TV_NSEC
864 ansec = st.st_atim.tv_nsec;
865 mnsec = st.st_mtim.tv_nsec;
866 cnsec = st.st_ctim.tv_nsec;
Fred Drake699f3522000-06-29 21:12:41 +0000867#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000868 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000869#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000870 fill_time(v, 7, st.st_atime, ansec);
871 fill_time(v, 8, st.st_mtime, mnsec);
872 fill_time(v, 9, st.st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000873
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000874#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +0000875 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000876 PyInt_FromLong((long)st.st_blksize));
877#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000878#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +0000879 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000880 PyInt_FromLong((long)st.st_blocks));
881#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000882#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000883 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
884 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000885#endif
886
887 if (PyErr_Occurred()) {
888 Py_DECREF(v);
889 return NULL;
890 }
891
892 return v;
893}
894
Barry Warsaw53699e91996-12-10 23:23:01 +0000895static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000896posix_do_stat(PyObject *self, PyObject *args,
897 char *format,
898 int (*statfunc)(const char *, STRUCT_STAT *),
899 char *wformat,
900 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000901{
Fred Drake699f3522000-06-29 21:12:41 +0000902 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +0000903 char *path = NULL; /* pass this to stat; do not free() it */
904 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000905 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000906
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000907#ifdef MS_WINDOWS
Tim Peters500bd032001-12-19 19:05:01 +0000908 int pathlen;
909 char pathcopy[MAX_PATH];
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000910#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000911
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000912
913#ifdef Py_WIN_WIDE_FILENAMES
914 /* If on wide-character-capable OS see if argument
915 is Unicode and if so use wide API. */
916 if (unicode_file_names()) {
917 PyUnicodeObject *po;
918 if (PyArg_ParseTuple(args, wformat, &po)) {
919 Py_UNICODE wpath[MAX_PATH+1];
920 pathlen = wcslen(PyUnicode_AS_UNICODE(po));
921 /* the library call can blow up if the file name is too long! */
922 if (pathlen > MAX_PATH) {
923 errno = ENAMETOOLONG;
924 return posix_error();
925 }
926 wcscpy(wpath, PyUnicode_AS_UNICODE(po));
927 /* Remove trailing slash or backslash, unless it's the current
928 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
929 */
930 if (pathlen > 0 &&
931 (wpath[pathlen-1]== L'\\' || wpath[pathlen-1] == L'/')) {
932 /* It does end with a slash -- exempt the root drive cases. */
933 /* XXX UNC root drives should also be exempted? */
934 if (pathlen == 1 || (pathlen == 3 && wpath[1] == L':'))
935 /* leave it alone */;
936 else {
937 /* nuke the trailing backslash */
938 wpath[pathlen-1] = L'\0';
939 }
940 }
941 Py_BEGIN_ALLOW_THREADS
942 /* PyUnicode_AS_UNICODE result OK without
943 thread lock as it is a simple dereference. */
944 res = wstatfunc(wpath, &st);
945 Py_END_ALLOW_THREADS
946 if (res != 0)
947 return posix_error_with_unicode_filename(wpath);
948 return _pystat_fromstructstat(st);
949 }
950 /* Drop the argument parsing error as narrow strings
951 are also valid. */
952 PyErr_Clear();
953 }
954#endif
955
Tim Peters5aa91602002-01-30 05:46:57 +0000956 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000957 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000958 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +0000959 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000960
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000961#ifdef MS_WINDOWS
Guido van Rossumace88ae2000-04-21 18:54:45 +0000962 pathlen = strlen(path);
963 /* the library call can blow up if the file name is too long! */
964 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +0000965 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000966 errno = ENAMETOOLONG;
967 return posix_error();
968 }
969
Tim Peters500bd032001-12-19 19:05:01 +0000970 /* Remove trailing slash or backslash, unless it's the current
971 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
972 */
973 if (pathlen > 0 &&
974 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
975 /* It does end with a slash -- exempt the root drive cases. */
976 /* XXX UNC root drives should also be exempted? */
977 if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
978 /* leave it alone */;
979 else {
980 /* nuke the trailing backslash */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000981 strncpy(pathcopy, path, pathlen);
Tim Peters500bd032001-12-19 19:05:01 +0000982 pathcopy[pathlen-1] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +0000983 path = pathcopy;
984 }
985 }
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000986#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000987
Barry Warsaw53699e91996-12-10 23:23:01 +0000988 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000989 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000990 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000991 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +0000992 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000993
Tim Peters500bd032001-12-19 19:05:01 +0000994 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000995 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000996}
997
998
999/* POSIX methods */
1000
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001001PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001002"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001003Use the real uid/gid to test for access to a path. Note that most\n\
1004operations will use the effective uid/gid, therefore this routine can\n\
1005be used in a suid/sgid environment to test if the invoking user has the\n\
1006specified access to the path. The mode argument can be F_OK to test\n\
1007existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001008
1009static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001010posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001011{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001012 char *path;
1013 int mode;
1014 int res;
1015
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001016 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001017 return NULL;
1018 Py_BEGIN_ALLOW_THREADS
1019 res = access(path, mode);
1020 Py_END_ALLOW_THREADS
Guido van Rossum674deb22002-09-01 15:06:28 +00001021 return(PyBool_FromLong(res == 0));
Guido van Rossum94f6f721999-01-06 18:42:14 +00001022}
1023
Guido van Rossumd371ff11999-01-25 16:12:23 +00001024#ifndef F_OK
1025#define F_OK 0
1026#endif
1027#ifndef R_OK
1028#define R_OK 4
1029#endif
1030#ifndef W_OK
1031#define W_OK 2
1032#endif
1033#ifndef X_OK
1034#define X_OK 1
1035#endif
1036
1037#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001038PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001039"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001040Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001041
1042static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001043posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001044{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001045 int id;
1046 char *ret;
1047
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001048 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001049 return NULL;
1050
Guido van Rossum94f6f721999-01-06 18:42:14 +00001051 ret = ttyname(id);
1052 if (ret == NULL)
1053 return(posix_error());
1054 return(PyString_FromString(ret));
1055}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001056#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001057
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001058#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001059PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001060"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001061Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001062
1063static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001064posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001065{
1066 char *ret;
1067 char buffer[L_ctermid];
1068
1069 if (!PyArg_ParseTuple(args, ":ctermid"))
1070 return NULL;
1071
Greg Wardb48bc172000-03-01 21:51:56 +00001072#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001073 ret = ctermid_r(buffer);
1074#else
1075 ret = ctermid(buffer);
1076#endif
1077 if (ret == NULL)
1078 return(posix_error());
1079 return(PyString_FromString(buffer));
1080}
1081#endif
1082
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001083PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001084"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001085Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001086
Barry Warsaw53699e91996-12-10 23:23:01 +00001087static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001088posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001089{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001090#ifdef MS_WINDOWS
1091 return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir);
1092#elif defined(PYOS_OS2) && defined(PYCC_GCC)
1093 return posix_1str(args, "et:chdir", _chdir2, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001094#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001095 return posix_1str(args, "et:chdir", chdir, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001096#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001097}
1098
Fred Drake4d1e64b2002-04-15 19:40:07 +00001099#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001100PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001101"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001102Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001103opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001104
1105static PyObject *
1106posix_fchdir(PyObject *self, PyObject *fdobj)
1107{
1108 return posix_fildes(fdobj, fchdir);
1109}
1110#endif /* HAVE_FCHDIR */
1111
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001112
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001113PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001114"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001115Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001116
Barry Warsaw53699e91996-12-10 23:23:01 +00001117static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001118posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001119{
Mark Hammondef8b6542001-05-13 08:04:26 +00001120 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001121 int i;
1122 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001123 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001124 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001125 return NULL;
1126 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001127 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001128 Py_END_ALLOW_THREADS
1129 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001130 return posix_error_with_allocated_filename(path);
1131 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001132 Py_INCREF(Py_None);
1133 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001134}
1135
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001136
Martin v. Löwis244edc82001-10-04 22:44:26 +00001137#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001138PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001139"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001140Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001141
1142static PyObject *
1143posix_chroot(PyObject *self, PyObject *args)
1144{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001145 return posix_1str(args, "et:chroot", chroot, NULL, NULL);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001146}
1147#endif
1148
Guido van Rossum21142a01999-01-08 21:05:37 +00001149#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001150PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001151"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001152force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001153
1154static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001155posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001156{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001157 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001158}
1159#endif /* HAVE_FSYNC */
1160
1161#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001162
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001163#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001164extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1165#endif
1166
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001167PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001168"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001169force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001170 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001171
1172static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001173posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001174{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001175 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001176}
1177#endif /* HAVE_FDATASYNC */
1178
1179
Fredrik Lundh10723342000-07-10 16:38:09 +00001180#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001181PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001182"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001183Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001184
Barry Warsaw53699e91996-12-10 23:23:01 +00001185static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001186posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001187{
Mark Hammondef8b6542001-05-13 08:04:26 +00001188 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001189 int uid, gid;
1190 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001191 if (!PyArg_ParseTuple(args, "etii:chown",
1192 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001193 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001194 return NULL;
1195 Py_BEGIN_ALLOW_THREADS
1196 res = chown(path, (uid_t) uid, (gid_t) gid);
1197 Py_END_ALLOW_THREADS
1198 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001199 return posix_error_with_allocated_filename(path);
1200 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001201 Py_INCREF(Py_None);
1202 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001203}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001204#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001205
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001206#ifdef HAVE_LCHOWN
1207PyDoc_STRVAR(posix_lchown__doc__,
1208"lchown(path, uid, gid)\n\n\
1209Change the owner and group id of path to the numeric uid and gid.\n\
1210This function will not follow symbolic links.");
1211
1212static PyObject *
1213posix_lchown(PyObject *self, PyObject *args)
1214{
1215 char *path = NULL;
1216 int uid, gid;
1217 int res;
1218 if (!PyArg_ParseTuple(args, "etii:lchown",
1219 Py_FileSystemDefaultEncoding, &path,
1220 &uid, &gid))
1221 return NULL;
1222 Py_BEGIN_ALLOW_THREADS
1223 res = lchown(path, (uid_t) uid, (gid_t) gid);
1224 Py_END_ALLOW_THREADS
1225 if (res < 0)
1226 return posix_error_with_allocated_filename(path);
1227 PyMem_Free(path);
1228 Py_INCREF(Py_None);
1229 return Py_None;
1230}
1231#endif /* HAVE_LCHOWN */
1232
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001233
Guido van Rossum36bc6801995-06-14 22:54:23 +00001234#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001235PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001236"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001237Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001238
Barry Warsaw53699e91996-12-10 23:23:01 +00001239static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001240posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001241{
1242 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001243 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001244 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001245 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001246 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001247#if defined(PYOS_OS2) && defined(PYCC_GCC)
1248 res = _getcwd2(buf, sizeof buf);
1249#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001250 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001251#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001252 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001253 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001254 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001255 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001256}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001257
Walter Dörwald3b918c32002-11-21 20:18:46 +00001258#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001259PyDoc_STRVAR(posix_getcwdu__doc__,
1260"getcwdu() -> path\n\n\
1261Return a unicode string representing the current working directory.");
1262
1263static PyObject *
1264posix_getcwdu(PyObject *self, PyObject *args)
1265{
1266 char buf[1026];
1267 char *res;
1268 if (!PyArg_ParseTuple(args, ":getcwd"))
1269 return NULL;
1270
1271#ifdef Py_WIN_WIDE_FILENAMES
1272 if (unicode_file_names()) {
1273 wchar_t *wres;
1274 wchar_t wbuf[1026];
1275 Py_BEGIN_ALLOW_THREADS
1276 wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
1277 Py_END_ALLOW_THREADS
1278 if (wres == NULL)
1279 return posix_error();
1280 return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
1281 }
1282#endif
1283
1284 Py_BEGIN_ALLOW_THREADS
1285#if defined(PYOS_OS2) && defined(PYCC_GCC)
1286 res = _getcwd2(buf, sizeof buf);
1287#else
1288 res = getcwd(buf, sizeof buf);
1289#endif
1290 Py_END_ALLOW_THREADS
1291 if (res == NULL)
1292 return posix_error();
1293 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1294}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001295#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00001296#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001297
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001298
Guido van Rossumb6775db1994-08-01 11:34:53 +00001299#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001300PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001301"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001302Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001303
Barry Warsaw53699e91996-12-10 23:23:01 +00001304static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001305posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001306{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001307 return posix_2str(args, "etet:link", link, NULL, NULL);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001308}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001309#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001310
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001311
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001312PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001313"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001314Return a list containing the names of the entries in the directory.\n\
1315\n\
1316 path: path of directory to list\n\
1317\n\
1318The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001319entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001320
Barry Warsaw53699e91996-12-10 23:23:01 +00001321static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001322posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001323{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001324 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001325 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001326#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001327
Barry Warsaw53699e91996-12-10 23:23:01 +00001328 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001329 HANDLE hFindFile;
1330 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001331 /* MAX_PATH characters could mean a bigger encoded string */
1332 char namebuf[MAX_PATH*2+5];
1333 char *bufptr = namebuf;
1334 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001335
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001336#ifdef Py_WIN_WIDE_FILENAMES
1337 /* If on wide-character-capable OS see if argument
1338 is Unicode and if so use wide API. */
1339 if (unicode_file_names()) {
1340 PyUnicodeObject *po;
1341 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1342 WIN32_FIND_DATAW wFileData;
1343 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1344 Py_UNICODE wch;
1345 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1346 wnamebuf[MAX_PATH] = L'\0';
1347 len = wcslen(wnamebuf);
1348 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1349 if (wch != L'/' && wch != L'\\' && wch != L':')
1350 wnamebuf[len++] = L'/';
1351 wcscpy(wnamebuf + len, L"*.*");
1352 if ((d = PyList_New(0)) == NULL)
1353 return NULL;
1354 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1355 if (hFindFile == INVALID_HANDLE_VALUE) {
1356 errno = GetLastError();
1357 if (errno == ERROR_FILE_NOT_FOUND) {
1358 return d;
1359 }
1360 Py_DECREF(d);
1361 return win32_error_unicode("FindFirstFileW", wnamebuf);
1362 }
1363 do {
1364 if (wFileData.cFileName[0] == L'.' &&
1365 (wFileData.cFileName[1] == L'\0' ||
1366 wFileData.cFileName[1] == L'.' &&
1367 wFileData.cFileName[2] == L'\0'))
1368 continue;
1369 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1370 if (v == NULL) {
1371 Py_DECREF(d);
1372 d = NULL;
1373 break;
1374 }
1375 if (PyList_Append(d, v) != 0) {
1376 Py_DECREF(v);
1377 Py_DECREF(d);
1378 d = NULL;
1379 break;
1380 }
1381 Py_DECREF(v);
1382 } while (FindNextFileW(hFindFile, &wFileData) == TRUE);
1383
1384 if (FindClose(hFindFile) == FALSE) {
1385 Py_DECREF(d);
1386 return win32_error_unicode("FindClose", wnamebuf);
1387 }
1388 return d;
1389 }
1390 /* Drop the argument parsing error as narrow strings
1391 are also valid. */
1392 PyErr_Clear();
1393 }
1394#endif
1395
Tim Peters5aa91602002-01-30 05:46:57 +00001396 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001397 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001398 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001399 if (len > 0) {
1400 char ch = namebuf[len-1];
1401 if (ch != SEP && ch != ALTSEP && ch != ':')
1402 namebuf[len++] = '/';
1403 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001404 strcpy(namebuf + len, "*.*");
1405
Barry Warsaw53699e91996-12-10 23:23:01 +00001406 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001407 return NULL;
1408
1409 hFindFile = FindFirstFile(namebuf, &FileData);
1410 if (hFindFile == INVALID_HANDLE_VALUE) {
1411 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001412 if (errno == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001413 return d;
1414 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001415 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001416 }
1417 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001418 if (FileData.cFileName[0] == '.' &&
1419 (FileData.cFileName[1] == '\0' ||
1420 FileData.cFileName[1] == '.' &&
1421 FileData.cFileName[2] == '\0'))
1422 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001423 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001424 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001425 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001426 d = NULL;
1427 break;
1428 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001429 if (PyList_Append(d, v) != 0) {
1430 Py_DECREF(v);
1431 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001432 d = NULL;
1433 break;
1434 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001435 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001436 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1437
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001438 if (FindClose(hFindFile) == FALSE) {
1439 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001440 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001441 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001442
1443 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001444
Tim Peters0bb44a42000-09-15 07:44:49 +00001445#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001446
1447#ifndef MAX_PATH
1448#define MAX_PATH CCHMAXPATH
1449#endif
1450 char *name, *pt;
1451 int len;
1452 PyObject *d, *v;
1453 char namebuf[MAX_PATH+5];
1454 HDIR hdir = 1;
1455 ULONG srchcnt = 1;
1456 FILEFINDBUF3 ep;
1457 APIRET rc;
1458
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001459 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001460 return NULL;
1461 if (len >= MAX_PATH) {
1462 PyErr_SetString(PyExc_ValueError, "path too long");
1463 return NULL;
1464 }
1465 strcpy(namebuf, name);
1466 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001467 if (*pt == ALTSEP)
1468 *pt = SEP;
1469 if (namebuf[len-1] != SEP)
1470 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001471 strcpy(namebuf + len, "*.*");
1472
1473 if ((d = PyList_New(0)) == NULL)
1474 return NULL;
1475
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001476 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1477 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001478 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001479 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1480 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1481 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001482
1483 if (rc != NO_ERROR) {
1484 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001485 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001486 }
1487
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001488 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001489 do {
1490 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001491 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001492 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001493
1494 strcpy(namebuf, ep.achName);
1495
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001496 /* Leave Case of Name Alone -- In Native Form */
1497 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001498
1499 v = PyString_FromString(namebuf);
1500 if (v == NULL) {
1501 Py_DECREF(d);
1502 d = NULL;
1503 break;
1504 }
1505 if (PyList_Append(d, v) != 0) {
1506 Py_DECREF(v);
1507 Py_DECREF(d);
1508 d = NULL;
1509 break;
1510 }
1511 Py_DECREF(v);
1512 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1513 }
1514
1515 return d;
1516#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001517
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001518 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001519 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001520 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001521 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001522 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001523 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001524 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001525 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001526 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001527 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001528 closedir(dirp);
1529 return NULL;
1530 }
1531 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001532 if (ep->d_name[0] == '.' &&
1533 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001534 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001535 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001536 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001537 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001538 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001539 d = NULL;
1540 break;
1541 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001542 if (PyList_Append(d, v) != 0) {
1543 Py_DECREF(v);
1544 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001545 d = NULL;
1546 break;
1547 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001548 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001549 }
1550 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001551
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001552 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001553
Tim Peters0bb44a42000-09-15 07:44:49 +00001554#endif /* which OS */
1555} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001556
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001557#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001558/* A helper function for abspath on win32 */
1559static PyObject *
1560posix__getfullpathname(PyObject *self, PyObject *args)
1561{
1562 /* assume encoded strings wont more than double no of chars */
1563 char inbuf[MAX_PATH*2];
1564 char *inbufp = inbuf;
1565 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1566 char outbuf[MAX_PATH*2];
1567 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001568#ifdef Py_WIN_WIDE_FILENAMES
1569 if (unicode_file_names()) {
1570 PyUnicodeObject *po;
1571 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1572 Py_UNICODE woutbuf[MAX_PATH*2];
1573 Py_UNICODE *wtemp;
1574 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
1575 sizeof(woutbuf)/sizeof(woutbuf[0]),
1576 woutbuf, &wtemp))
1577 return win32_error("GetFullPathName", "");
1578 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1579 }
1580 /* Drop the argument parsing error as narrow strings
1581 are also valid. */
1582 PyErr_Clear();
1583 }
1584#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001585 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1586 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001587 &insize))
1588 return NULL;
1589 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1590 outbuf, &temp))
1591 return win32_error("GetFullPathName", inbuf);
1592 return PyString_FromString(outbuf);
1593} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001594#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001595
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001596PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001597"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001598Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001599
Barry Warsaw53699e91996-12-10 23:23:01 +00001600static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001601posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001602{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001603 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001604 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001605 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001606
1607#ifdef Py_WIN_WIDE_FILENAMES
1608 if (unicode_file_names()) {
1609 PyUnicodeObject *po;
1610 if (PyArg_ParseTuple(args, "U|i:mkdir", &po)) {
1611 Py_BEGIN_ALLOW_THREADS
1612 /* PyUnicode_AS_UNICODE OK without thread lock as
1613 it is a simple dereference. */
1614 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1615 Py_END_ALLOW_THREADS
1616 if (res < 0)
1617 return posix_error();
1618 Py_INCREF(Py_None);
1619 return Py_None;
1620 }
1621 /* Drop the argument parsing error as narrow strings
1622 are also valid. */
1623 PyErr_Clear();
1624 }
1625#endif
1626
Tim Peters5aa91602002-01-30 05:46:57 +00001627 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001628 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001629 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001630 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001631#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001632 res = mkdir(path);
1633#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001634 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001635#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001636 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001637 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001638 return posix_error_with_allocated_filename(path);
1639 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001640 Py_INCREF(Py_None);
1641 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001642}
1643
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001644
Guido van Rossumb6775db1994-08-01 11:34:53 +00001645#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001646#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1647#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1648#include <sys/resource.h>
1649#endif
1650#endif
1651
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001652PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001653"nice(inc) -> new_priority\n\n\
1654Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001655
Barry Warsaw53699e91996-12-10 23:23:01 +00001656static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001657posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001658{
1659 int increment, value;
1660
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001661 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001662 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001663
1664 /* There are two flavours of 'nice': one that returns the new
1665 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001666 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1667 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001668
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001669 If we are of the nice family that returns the new priority, we
1670 need to clear errno before the call, and check if errno is filled
1671 before calling posix_error() on a returnvalue of -1, because the
1672 -1 may be the actual new priority! */
1673
1674 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001675 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001676#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001677 if (value == 0)
1678 value = getpriority(PRIO_PROCESS, 0);
1679#endif
1680 if (value == -1 && errno != 0)
1681 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001682 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001683 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001684}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001685#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001686
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001687
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001688PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001689"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001690Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001691
Barry Warsaw53699e91996-12-10 23:23:01 +00001692static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001693posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001694{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001695#ifdef MS_WINDOWS
1696 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
1697#else
1698 return posix_2str(args, "etet:rename", rename, NULL, NULL);
1699#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001700}
1701
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001702
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001703PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001704"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001705Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001706
Barry Warsaw53699e91996-12-10 23:23:01 +00001707static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001708posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001709{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001710#ifdef MS_WINDOWS
1711 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
1712#else
1713 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
1714#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001715}
1716
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001717
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001718PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001719"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001720Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001721
Barry Warsaw53699e91996-12-10 23:23:01 +00001722static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001723posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001724{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001725#ifdef MS_WINDOWS
1726 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", _wstati64);
1727#else
1728 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
1729#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001730}
1731
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001732
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001733#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001734PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001735"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001736Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001737
Barry Warsaw53699e91996-12-10 23:23:01 +00001738static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001739posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001740{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001741 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001742 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001743 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001744 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001745 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001746 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001747 Py_END_ALLOW_THREADS
1748 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001749}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001750#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001751
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001752
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001753PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001754"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001755Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001756
Barry Warsaw53699e91996-12-10 23:23:01 +00001757static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001758posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001759{
1760 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001761 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001762 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001763 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001764 if (i < 0)
1765 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001766 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001767}
1768
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001769
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001770PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001771"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001772Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001773
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001774PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001775"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001776Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001777
Barry Warsaw53699e91996-12-10 23:23:01 +00001778static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001779posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001780{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001781#ifdef MS_WINDOWS
1782 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
1783#else
1784 return posix_1str(args, "et:remove", unlink, NULL, NULL);
1785#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001786}
1787
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001788
Guido van Rossumb6775db1994-08-01 11:34:53 +00001789#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001790PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001791"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001792Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001793
Barry Warsaw53699e91996-12-10 23:23:01 +00001794static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001795posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001796{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001797 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001798 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001799 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001800 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001801 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001802 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001803 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001804 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001805 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001806 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001807 u.sysname,
1808 u.nodename,
1809 u.release,
1810 u.version,
1811 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001812}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001813#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001814
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001815static int
1816extract_time(PyObject *t, long* sec, long* usec)
1817{
1818 long intval;
1819 if (PyFloat_Check(t)) {
1820 double tval = PyFloat_AsDouble(t);
1821 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
1822 if (!intobj)
1823 return -1;
1824 intval = PyInt_AsLong(intobj);
1825 Py_DECREF(intobj);
1826 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00001827 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001828 if (*usec < 0)
1829 /* If rounding gave us a negative number,
1830 truncate. */
1831 *usec = 0;
1832 return 0;
1833 }
1834 intval = PyInt_AsLong(t);
1835 if (intval == -1 && PyErr_Occurred())
1836 return -1;
1837 *sec = intval;
1838 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00001839 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001840}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001841
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001842PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001843"utime(path, (atime, utime))\n\
1844utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001845Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001846second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001847
Barry Warsaw53699e91996-12-10 23:23:01 +00001848static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001849posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001850{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001851 char *path;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001852 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001853 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001854 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001855
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001856#if defined(HAVE_UTIMES)
1857 struct timeval buf[2];
1858#define ATIME buf[0].tv_sec
1859#define MTIME buf[1].tv_sec
1860#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001861/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001862 struct utimbuf buf;
1863#define ATIME buf.actime
1864#define MTIME buf.modtime
1865#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001866#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001867 time_t buf[2];
1868#define ATIME buf[0]
1869#define MTIME buf[1]
1870#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001871#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001872
Barry Warsaw3cef8562000-05-01 16:17:24 +00001873 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001874 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001875 if (arg == Py_None) {
1876 /* optional time values not given */
1877 Py_BEGIN_ALLOW_THREADS
1878 res = utime(path, NULL);
1879 Py_END_ALLOW_THREADS
1880 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001881 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00001882 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001883 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001884 return NULL;
1885 }
1886 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001887 if (extract_time(PyTuple_GET_ITEM(arg, 0),
1888 &atime, &ausec) == -1)
1889 return NULL;
1890 if (extract_time(PyTuple_GET_ITEM(arg, 1),
1891 &mtime, &musec) == -1)
1892 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001893 ATIME = atime;
1894 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001895#ifdef HAVE_UTIMES
1896 buf[0].tv_usec = ausec;
1897 buf[1].tv_usec = musec;
1898 Py_BEGIN_ALLOW_THREADS
1899 res = utimes(path, buf);
1900 Py_END_ALLOW_THREADS
1901#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00001902 Py_BEGIN_ALLOW_THREADS
1903 res = utime(path, UTIME_ARG);
1904 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001905#endif
Barry Warsaw3cef8562000-05-01 16:17:24 +00001906 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001907 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001908 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001909 Py_INCREF(Py_None);
1910 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001911#undef UTIME_ARG
1912#undef ATIME
1913#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001914}
1915
Guido van Rossum85e3b011991-06-03 12:42:10 +00001916
Guido van Rossum3b066191991-06-04 19:40:25 +00001917/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001918
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001919PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001920"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001921Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001922
Barry Warsaw53699e91996-12-10 23:23:01 +00001923static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001924posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001925{
1926 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001927 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001928 return NULL;
1929 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001930 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001931}
1932
Martin v. Löwis114619e2002-10-07 06:44:21 +00001933#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
1934static void
1935free_string_array(char **array, int count)
1936{
1937 int i;
1938 for (i = 0; i < count; i++)
1939 PyMem_Free(array[i]);
1940 PyMem_DEL(array);
1941}
1942#endif
1943
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001944
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001945#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001946PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001947"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001948Execute an executable path with arguments, replacing current process.\n\
1949\n\
1950 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001951 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001952
Barry Warsaw53699e91996-12-10 23:23:01 +00001953static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001954posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001955{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001956 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001957 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001958 char **argvlist;
1959 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001960 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001961
Guido van Rossum89b33251993-10-22 14:26:06 +00001962 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001963 argv is a list or tuple of strings. */
1964
Martin v. Löwis114619e2002-10-07 06:44:21 +00001965 if (!PyArg_ParseTuple(args, "etO:execv",
1966 Py_FileSystemDefaultEncoding,
1967 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001968 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001969 if (PyList_Check(argv)) {
1970 argc = PyList_Size(argv);
1971 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001972 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001973 else if (PyTuple_Check(argv)) {
1974 argc = PyTuple_Size(argv);
1975 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001976 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001977 else {
Fred Drake661ea262000-10-24 19:57:45 +00001978 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00001979 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00001980 return NULL;
1981 }
1982
1983 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001984 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00001985 PyMem_Free(path);
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001986 return NULL;
1987 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001988
Barry Warsaw53699e91996-12-10 23:23:01 +00001989 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00001990 if (argvlist == NULL) {
1991 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001992 return NULL;
Martin v. Löwis114619e2002-10-07 06:44:21 +00001993 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001994 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00001995 if (!PyArg_Parse((*getitem)(argv, i), "et",
1996 Py_FileSystemDefaultEncoding,
1997 &argvlist[i])) {
1998 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00001999 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002000 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002001 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002002 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002003
Guido van Rossum85e3b011991-06-03 12:42:10 +00002004 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002005 }
2006 argvlist[argc] = NULL;
2007
Guido van Rossumb6775db1994-08-01 11:34:53 +00002008#ifdef BAD_EXEC_PROTOTYPES
2009 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002010#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002011 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002012#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002013
Guido van Rossum85e3b011991-06-03 12:42:10 +00002014 /* If we get here it's definitely an error */
2015
Martin v. Löwis114619e2002-10-07 06:44:21 +00002016 free_string_array(argvlist, argc);
2017 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002018 return posix_error();
2019}
2020
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002021
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002022PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002023"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002024Execute a path with arguments and environment, replacing current process.\n\
2025\n\
2026 path: path of executable file\n\
2027 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002028 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002029
Barry Warsaw53699e91996-12-10 23:23:01 +00002030static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002031posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002032{
2033 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002034 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002035 char **argvlist;
2036 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002037 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002038 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002039 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002040 int lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002041
2042 /* execve has three arguments: (path, argv, env), where
2043 argv is a list or tuple of strings and env is a dictionary
2044 like posix.environ. */
2045
Martin v. Löwis114619e2002-10-07 06:44:21 +00002046 if (!PyArg_ParseTuple(args, "etOO:execve",
2047 Py_FileSystemDefaultEncoding,
2048 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002049 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002050 if (PyList_Check(argv)) {
2051 argc = PyList_Size(argv);
2052 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002053 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002054 else if (PyTuple_Check(argv)) {
2055 argc = PyTuple_Size(argv);
2056 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002057 }
2058 else {
Fred Drake661ea262000-10-24 19:57:45 +00002059 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002060 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002061 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002062 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00002063 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002064 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002065 }
2066
Guido van Rossum50422b42000-04-26 20:34:28 +00002067 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00002068 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00002069 "execve() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002070 goto fail_0;
Guido van Rossum50422b42000-04-26 20:34:28 +00002071 }
2072
Barry Warsaw53699e91996-12-10 23:23:01 +00002073 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002074 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002075 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002076 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002077 }
2078 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002079 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002080 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002081 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002082 &argvlist[i]))
2083 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002084 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002085 goto fail_1;
2086 }
2087 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002088 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002089 argvlist[argc] = NULL;
2090
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002091 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00002092 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002093 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002094 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002095 goto fail_1;
2096 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002097 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002098 keys = PyMapping_Keys(env);
2099 vals = PyMapping_Values(env);
2100 if (!keys || !vals)
2101 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002102
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002103 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002104 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002105 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002106
2107 key = PyList_GetItem(keys, pos);
2108 val = PyList_GetItem(vals, pos);
2109 if (!key || !val)
2110 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002111
Fred Drake661ea262000-10-24 19:57:45 +00002112 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
2113 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002114 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002115 goto fail_2;
2116 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002117
2118#if defined(PYOS_OS2)
2119 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2120 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2121#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002122 len = PyString_Size(key) + PyString_Size(val) + 2;
2123 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002124 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002125 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002126 goto fail_2;
2127 }
Tim Petersc8996f52001-12-03 20:41:00 +00002128 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002129 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002130#if defined(PYOS_OS2)
2131 }
2132#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002133 }
2134 envlist[envc] = 0;
2135
Guido van Rossumb6775db1994-08-01 11:34:53 +00002136
2137#ifdef BAD_EXEC_PROTOTYPES
2138 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002139#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002140 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002141#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00002142
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002143 /* If we get here it's definitely an error */
2144
2145 (void) posix_error();
2146
2147 fail_2:
2148 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002149 PyMem_DEL(envlist[envc]);
2150 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002151 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002152 free_string_array(argvlist,lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002153 Py_XDECREF(vals);
2154 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002155 fail_0:
2156 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002157 return NULL;
2158}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002159#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002160
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002161
Guido van Rossuma1065681999-01-25 23:20:23 +00002162#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002163PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002164"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002165Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002166\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002167 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002168 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002169 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002170
2171static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002172posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002173{
2174 char *path;
2175 PyObject *argv;
2176 char **argvlist;
2177 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002178 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002179 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00002180
2181 /* spawnv has three arguments: (mode, path, argv), where
2182 argv is a list or tuple of strings. */
2183
Martin v. Löwis114619e2002-10-07 06:44:21 +00002184 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2185 Py_FileSystemDefaultEncoding,
2186 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002187 return NULL;
2188 if (PyList_Check(argv)) {
2189 argc = PyList_Size(argv);
2190 getitem = PyList_GetItem;
2191 }
2192 else if (PyTuple_Check(argv)) {
2193 argc = PyTuple_Size(argv);
2194 getitem = PyTuple_GetItem;
2195 }
2196 else {
Martin v. Löwise75f0e42001-11-24 09:31:44 +00002197 PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002198 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002199 return NULL;
2200 }
2201
2202 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002203 if (argvlist == NULL) {
2204 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002205 return NULL;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002206 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002207 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002208 if (!PyArg_Parse((*getitem)(argv, i), "et",
2209 Py_FileSystemDefaultEncoding,
2210 &argvlist[i])) {
2211 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002212 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002213 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002214 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002215 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002216 }
2217 }
2218 argvlist[argc] = NULL;
2219
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002220#if defined(PYOS_OS2) && defined(PYCC_GCC)
2221 Py_BEGIN_ALLOW_THREADS
2222 spawnval = spawnv(mode, path, argvlist);
2223 Py_END_ALLOW_THREADS
2224#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002225 if (mode == _OLD_P_OVERLAY)
2226 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002227
Tim Peters25059d32001-12-07 20:35:43 +00002228 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002229 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002230 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002231#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002232
Martin v. Löwis114619e2002-10-07 06:44:21 +00002233 free_string_array(argvlist, argc);
2234 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002235
Fred Drake699f3522000-06-29 21:12:41 +00002236 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002237 return posix_error();
2238 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002239#if SIZEOF_LONG == SIZEOF_VOID_P
2240 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002241#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002242 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002243#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002244}
2245
2246
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002247PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002248"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002249Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002250\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002251 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002252 path: path of executable file\n\
2253 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002254 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002255
2256static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002257posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002258{
2259 char *path;
2260 PyObject *argv, *env;
2261 char **argvlist;
2262 char **envlist;
2263 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2264 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002265 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002266 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002267 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002268
2269 /* spawnve has four arguments: (mode, path, argv, env), where
2270 argv is a list or tuple of strings and env is a dictionary
2271 like posix.environ. */
2272
Martin v. Löwis114619e2002-10-07 06:44:21 +00002273 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2274 Py_FileSystemDefaultEncoding,
2275 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002276 return NULL;
2277 if (PyList_Check(argv)) {
2278 argc = PyList_Size(argv);
2279 getitem = PyList_GetItem;
2280 }
2281 else if (PyTuple_Check(argv)) {
2282 argc = PyTuple_Size(argv);
2283 getitem = PyTuple_GetItem;
2284 }
2285 else {
Fred Drake661ea262000-10-24 19:57:45 +00002286 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002287 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002288 }
2289 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00002290 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002291 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002292 }
2293
2294 argvlist = PyMem_NEW(char *, argc+1);
2295 if (argvlist == NULL) {
2296 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002297 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002298 }
2299 for (i = 0; i < argc; i++) {
2300 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002301 "et;spawnve() arg 2 must contain only strings",
2302 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002303 &argvlist[i]))
2304 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002305 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002306 goto fail_1;
2307 }
2308 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002309 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002310 argvlist[argc] = NULL;
2311
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002312 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00002313 envlist = PyMem_NEW(char *, i + 1);
2314 if (envlist == NULL) {
2315 PyErr_NoMemory();
2316 goto fail_1;
2317 }
2318 envc = 0;
2319 keys = PyMapping_Keys(env);
2320 vals = PyMapping_Values(env);
2321 if (!keys || !vals)
2322 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002323
Guido van Rossuma1065681999-01-25 23:20:23 +00002324 for (pos = 0; pos < i; pos++) {
2325 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002326 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002327
2328 key = PyList_GetItem(keys, pos);
2329 val = PyList_GetItem(vals, pos);
2330 if (!key || !val)
2331 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002332
Fred Drake661ea262000-10-24 19:57:45 +00002333 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
2334 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002335 {
2336 goto fail_2;
2337 }
Tim Petersc8996f52001-12-03 20:41:00 +00002338 len = PyString_Size(key) + PyString_Size(val) + 2;
2339 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002340 if (p == NULL) {
2341 PyErr_NoMemory();
2342 goto fail_2;
2343 }
Tim Petersc8996f52001-12-03 20:41:00 +00002344 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002345 envlist[envc++] = p;
2346 }
2347 envlist[envc] = 0;
2348
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002349#if defined(PYOS_OS2) && defined(PYCC_GCC)
2350 Py_BEGIN_ALLOW_THREADS
2351 spawnval = spawnve(mode, path, argvlist, envlist);
2352 Py_END_ALLOW_THREADS
2353#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002354 if (mode == _OLD_P_OVERLAY)
2355 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002356
2357 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002358 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002359 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002360#endif
Tim Peters25059d32001-12-07 20:35:43 +00002361
Fred Drake699f3522000-06-29 21:12:41 +00002362 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002363 (void) posix_error();
2364 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002365#if SIZEOF_LONG == SIZEOF_VOID_P
2366 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002367#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002368 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002369#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002370
2371 fail_2:
2372 while (--envc >= 0)
2373 PyMem_DEL(envlist[envc]);
2374 PyMem_DEL(envlist);
2375 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002376 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002377 Py_XDECREF(vals);
2378 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002379 fail_0:
2380 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002381 return res;
2382}
2383#endif /* HAVE_SPAWNV */
2384
2385
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002386#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002387PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002388"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002389Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
2390\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002391Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002392
2393static PyObject *
2394posix_fork1(self, args)
2395 PyObject *self;
2396 PyObject *args;
2397{
2398 int pid;
2399 if (!PyArg_ParseTuple(args, ":fork1"))
2400 return NULL;
2401 pid = fork1();
2402 if (pid == -1)
2403 return posix_error();
2404 PyOS_AfterFork();
2405 return PyInt_FromLong((long)pid);
2406}
2407#endif
2408
2409
Guido van Rossumad0ee831995-03-01 10:34:45 +00002410#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002411PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002412"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002413Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002414Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002415
Barry Warsaw53699e91996-12-10 23:23:01 +00002416static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002417posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002418{
2419 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002420 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00002421 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002422 pid = fork();
2423 if (pid == -1)
2424 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002425 if (pid == 0)
2426 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00002427 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002428}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002429#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002430
Fred Drake8cef4cf2000-06-28 16:40:38 +00002431#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
2432#ifdef HAVE_PTY_H
2433#include <pty.h>
2434#else
2435#ifdef HAVE_LIBUTIL_H
2436#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00002437#endif /* HAVE_LIBUTIL_H */
2438#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002439#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002440
Thomas Wouters70c21a12000-07-14 14:28:33 +00002441#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002442PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002443"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002444Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002445
2446static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002447posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002448{
2449 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002450#ifndef HAVE_OPENPTY
2451 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002452#endif
2453
Fred Drake8cef4cf2000-06-28 16:40:38 +00002454 if (!PyArg_ParseTuple(args, ":openpty"))
2455 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002456
2457#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00002458 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2459 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00002460#else
2461 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2462 if (slave_name == NULL)
2463 return posix_error();
2464
2465 slave_fd = open(slave_name, O_RDWR);
2466 if (slave_fd < 0)
2467 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00002468#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002469
Fred Drake8cef4cf2000-06-28 16:40:38 +00002470 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00002471
Fred Drake8cef4cf2000-06-28 16:40:38 +00002472}
Thomas Wouters70c21a12000-07-14 14:28:33 +00002473#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002474
2475#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002476PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002477"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00002478Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2479Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002480To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002481
2482static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002483posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002484{
2485 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002486
Fred Drake8cef4cf2000-06-28 16:40:38 +00002487 if (!PyArg_ParseTuple(args, ":forkpty"))
2488 return NULL;
2489 pid = forkpty(&master_fd, NULL, NULL, NULL);
2490 if (pid == -1)
2491 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002492 if (pid == 0)
2493 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002494 return Py_BuildValue("(ii)", pid, master_fd);
2495}
2496#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002497
Guido van Rossumad0ee831995-03-01 10:34:45 +00002498#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002499PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002500"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002501Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002502
Barry Warsaw53699e91996-12-10 23:23:01 +00002503static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002504posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002505{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002506 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002507 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002508 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002509}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002510#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002511
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002512
Guido van Rossumad0ee831995-03-01 10:34:45 +00002513#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002514PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002515"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002516Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002517
Barry Warsaw53699e91996-12-10 23:23:01 +00002518static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002519posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002520{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002521 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002522 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002523 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002524}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002525#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002526
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002527
Guido van Rossumad0ee831995-03-01 10:34:45 +00002528#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002529PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002530"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002531Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002532
Barry Warsaw53699e91996-12-10 23:23:01 +00002533static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002534posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002535{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002536 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002537 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002538 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002539}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002540#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002541
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002542
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002543PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002544"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002545Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002546
Barry Warsaw53699e91996-12-10 23:23:01 +00002547static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002548posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002549{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002550 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002551 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002552 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002553}
2554
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002555
Fred Drakec9680921999-12-13 16:37:25 +00002556#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002557PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002558"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002559Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00002560
2561static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002562posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002563{
2564 PyObject *result = NULL;
2565
2566 if (PyArg_ParseTuple(args, ":getgroups")) {
2567#ifdef NGROUPS_MAX
2568#define MAX_GROUPS NGROUPS_MAX
2569#else
2570 /* defined to be 16 on Solaris7, so this should be a small number */
2571#define MAX_GROUPS 64
2572#endif
2573 gid_t grouplist[MAX_GROUPS];
2574 int n;
2575
2576 n = getgroups(MAX_GROUPS, grouplist);
2577 if (n < 0)
2578 posix_error();
2579 else {
2580 result = PyList_New(n);
2581 if (result != NULL) {
2582 PyObject *o;
2583 int i;
2584 for (i = 0; i < n; ++i) {
2585 o = PyInt_FromLong((long)grouplist[i]);
2586 if (o == NULL) {
2587 Py_DECREF(result);
2588 result = NULL;
2589 break;
2590 }
2591 PyList_SET_ITEM(result, i, o);
2592 }
2593 }
2594 }
2595 }
2596 return result;
2597}
2598#endif
2599
Martin v. Löwis606edc12002-06-13 21:09:11 +00002600#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002601PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002602"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002603Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00002604
2605static PyObject *
2606posix_getpgid(PyObject *self, PyObject *args)
2607{
2608 int pid, pgid;
2609 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
2610 return NULL;
2611 pgid = getpgid(pid);
2612 if (pgid < 0)
2613 return posix_error();
2614 return PyInt_FromLong((long)pgid);
2615}
2616#endif /* HAVE_GETPGID */
2617
2618
Guido van Rossumb6775db1994-08-01 11:34:53 +00002619#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002620PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002621"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002622Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002623
Barry Warsaw53699e91996-12-10 23:23:01 +00002624static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002625posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002626{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002627 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002628 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002629#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002630 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002631#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002632 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002633#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002634}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002635#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002636
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002637
Guido van Rossumb6775db1994-08-01 11:34:53 +00002638#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002639PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002640"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002641Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002642
Barry Warsaw53699e91996-12-10 23:23:01 +00002643static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002644posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002645{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002646 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002647 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002648#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002649 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002650#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002651 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002652#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002653 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002654 Py_INCREF(Py_None);
2655 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002656}
2657
Guido van Rossumb6775db1994-08-01 11:34:53 +00002658#endif /* HAVE_SETPGRP */
2659
Guido van Rossumad0ee831995-03-01 10:34:45 +00002660#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002661PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002662"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002663Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002664
Barry Warsaw53699e91996-12-10 23:23:01 +00002665static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002666posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002667{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002668 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002669 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002670 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002671}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002672#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002673
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002674
Fred Drake12c6e2d1999-12-14 21:25:03 +00002675#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002676PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002677"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002678Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00002679
2680static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002681posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002682{
2683 PyObject *result = NULL;
2684
2685 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002686 char *name;
2687 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002688
Fred Drakea30680b2000-12-06 21:24:28 +00002689 errno = 0;
2690 name = getlogin();
2691 if (name == NULL) {
2692 if (errno)
2693 posix_error();
2694 else
2695 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002696 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002697 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002698 else
2699 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002700 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002701 }
2702 return result;
2703}
2704#endif
2705
Guido van Rossumad0ee831995-03-01 10:34:45 +00002706#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002707PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002708"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002709Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002710
Barry Warsaw53699e91996-12-10 23:23:01 +00002711static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002712posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002713{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002714 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002715 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002716 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002717}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002718#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002719
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002720
Guido van Rossumad0ee831995-03-01 10:34:45 +00002721#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002722PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002723"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002724Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002725
Barry Warsaw53699e91996-12-10 23:23:01 +00002726static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002727posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002728{
2729 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002730 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002731 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002732#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002733 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2734 APIRET rc;
2735 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002736 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002737
2738 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2739 APIRET rc;
2740 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002741 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002742
2743 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002744 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002745#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002746 if (kill(pid, sig) == -1)
2747 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002748#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002749 Py_INCREF(Py_None);
2750 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002751}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002752#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002753
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002754#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002755PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002756"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002757Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002758
2759static PyObject *
2760posix_killpg(PyObject *self, PyObject *args)
2761{
2762 int pgid, sig;
2763 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
2764 return NULL;
2765 if (killpg(pgid, sig) == -1)
2766 return posix_error();
2767 Py_INCREF(Py_None);
2768 return Py_None;
2769}
2770#endif
2771
Guido van Rossumc0125471996-06-28 18:55:32 +00002772#ifdef HAVE_PLOCK
2773
2774#ifdef HAVE_SYS_LOCK_H
2775#include <sys/lock.h>
2776#endif
2777
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002778PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002779"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002780Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002781
Barry Warsaw53699e91996-12-10 23:23:01 +00002782static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002783posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002784{
2785 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002786 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002787 return NULL;
2788 if (plock(op) == -1)
2789 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002790 Py_INCREF(Py_None);
2791 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002792}
2793#endif
2794
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002795
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002796#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002797PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002798"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002799Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002800
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002801#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002802#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002803static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002804async_system(const char *command)
2805{
2806 char *p, errormsg[256], args[1024];
2807 RESULTCODES rcodes;
2808 APIRET rc;
2809 char *shell = getenv("COMSPEC");
2810 if (!shell)
2811 shell = "cmd";
2812
2813 strcpy(args, shell);
2814 p = &args[ strlen(args)+1 ];
2815 strcpy(p, "/c ");
2816 strcat(p, command);
2817 p += strlen(p) + 1;
2818 *p = '\0';
2819
2820 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002821 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002822 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002823 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002824 &rcodes, shell);
2825 return rc;
2826}
2827
Guido van Rossumd48f2521997-12-05 22:19:34 +00002828static FILE *
2829popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002830{
2831 HFILE rhan, whan;
2832 FILE *retfd = NULL;
2833 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2834
Guido van Rossumd48f2521997-12-05 22:19:34 +00002835 if (rc != NO_ERROR) {
2836 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002837 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002838 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002839
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002840 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2841 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002842
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002843 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2844 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002845
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002846 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2847 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002848
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002849 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002850 }
2851
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002852 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2853 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002854
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002855 if (rc == NO_ERROR)
2856 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2857
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002858 close(oldfd); /* And Close Saved STDOUT Handle */
2859 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002860
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002861 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2862 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002863
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002864 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2865 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002866
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002867 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2868 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002869
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002870 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002871 }
2872
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002873 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2874 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002875
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002876 if (rc == NO_ERROR)
2877 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2878
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002879 close(oldfd); /* And Close Saved STDIN Handle */
2880 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002881
Guido van Rossumd48f2521997-12-05 22:19:34 +00002882 } else {
2883 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002884 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002885 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002886}
2887
2888static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002889posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002890{
2891 char *name;
2892 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002893 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002894 FILE *fp;
2895 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002896 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002897 return NULL;
2898 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002899 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002900 Py_END_ALLOW_THREADS
2901 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002902 return os2_error(err);
2903
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002904 f = PyFile_FromFile(fp, name, mode, fclose);
2905 if (f != NULL)
2906 PyFile_SetBufSize(f, bufsize);
2907 return f;
2908}
2909
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002910#elif defined(PYCC_GCC)
2911
2912/* standard posix version of popen() support */
2913static PyObject *
2914posix_popen(PyObject *self, PyObject *args)
2915{
2916 char *name;
2917 char *mode = "r";
2918 int bufsize = -1;
2919 FILE *fp;
2920 PyObject *f;
2921 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2922 return NULL;
2923 Py_BEGIN_ALLOW_THREADS
2924 fp = popen(name, mode);
2925 Py_END_ALLOW_THREADS
2926 if (fp == NULL)
2927 return posix_error();
2928 f = PyFile_FromFile(fp, name, mode, pclose);
2929 if (f != NULL)
2930 PyFile_SetBufSize(f, bufsize);
2931 return f;
2932}
2933
2934/* fork() under OS/2 has lots'o'warts
2935 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
2936 * most of this code is a ripoff of the win32 code, but using the
2937 * capabilities of EMX's C library routines
2938 */
2939
2940/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
2941#define POPEN_1 1
2942#define POPEN_2 2
2943#define POPEN_3 3
2944#define POPEN_4 4
2945
2946static PyObject *_PyPopen(char *, int, int, int);
2947static int _PyPclose(FILE *file);
2948
2949/*
2950 * Internal dictionary mapping popen* file pointers to process handles,
2951 * for use when retrieving the process exit code. See _PyPclose() below
2952 * for more information on this dictionary's use.
2953 */
2954static PyObject *_PyPopenProcs = NULL;
2955
2956/* os2emx version of popen2()
2957 *
2958 * The result of this function is a pipe (file) connected to the
2959 * process's stdin, and a pipe connected to the process's stdout.
2960 */
2961
2962static PyObject *
2963os2emx_popen2(PyObject *self, PyObject *args)
2964{
2965 PyObject *f;
2966 int tm=0;
2967
2968 char *cmdstring;
2969 char *mode = "t";
2970 int bufsize = -1;
2971 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
2972 return NULL;
2973
2974 if (*mode == 't')
2975 tm = O_TEXT;
2976 else if (*mode != 'b') {
2977 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2978 return NULL;
2979 } else
2980 tm = O_BINARY;
2981
2982 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
2983
2984 return f;
2985}
2986
2987/*
2988 * Variation on os2emx.popen2
2989 *
2990 * The result of this function is 3 pipes - the process's stdin,
2991 * stdout and stderr
2992 */
2993
2994static PyObject *
2995os2emx_popen3(PyObject *self, PyObject *args)
2996{
2997 PyObject *f;
2998 int tm = 0;
2999
3000 char *cmdstring;
3001 char *mode = "t";
3002 int bufsize = -1;
3003 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3004 return NULL;
3005
3006 if (*mode == 't')
3007 tm = O_TEXT;
3008 else if (*mode != 'b') {
3009 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3010 return NULL;
3011 } else
3012 tm = O_BINARY;
3013
3014 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3015
3016 return f;
3017}
3018
3019/*
3020 * Variation on os2emx.popen2
3021 *
3022 * The result of this function is 2 pipes - the processes stdin,
3023 * and stdout+stderr combined as a single pipe.
3024 */
3025
3026static PyObject *
3027os2emx_popen4(PyObject *self, PyObject *args)
3028{
3029 PyObject *f;
3030 int tm = 0;
3031
3032 char *cmdstring;
3033 char *mode = "t";
3034 int bufsize = -1;
3035 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3036 return NULL;
3037
3038 if (*mode == 't')
3039 tm = O_TEXT;
3040 else if (*mode != 'b') {
3041 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3042 return NULL;
3043 } else
3044 tm = O_BINARY;
3045
3046 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3047
3048 return f;
3049}
3050
3051/* a couple of structures for convenient handling of multiple
3052 * file handles and pipes
3053 */
3054struct file_ref
3055{
3056 int handle;
3057 int flags;
3058};
3059
3060struct pipe_ref
3061{
3062 int rd;
3063 int wr;
3064};
3065
3066/* The following code is derived from the win32 code */
3067
3068static PyObject *
3069_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3070{
3071 struct file_ref stdio[3];
3072 struct pipe_ref p_fd[3];
3073 FILE *p_s[3];
3074 int file_count, i, pipe_err, pipe_pid;
3075 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3076 PyObject *f, *p_f[3];
3077
3078 /* file modes for subsequent fdopen's on pipe handles */
3079 if (mode == O_TEXT)
3080 {
3081 rd_mode = "rt";
3082 wr_mode = "wt";
3083 }
3084 else
3085 {
3086 rd_mode = "rb";
3087 wr_mode = "wb";
3088 }
3089
3090 /* prepare shell references */
3091 if ((shell = getenv("EMXSHELL")) == NULL)
3092 if ((shell = getenv("COMSPEC")) == NULL)
3093 {
3094 errno = ENOENT;
3095 return posix_error();
3096 }
3097
3098 sh_name = _getname(shell);
3099 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3100 opt = "/c";
3101 else
3102 opt = "-c";
3103
3104 /* save current stdio fds + their flags, and set not inheritable */
3105 i = pipe_err = 0;
3106 while (pipe_err >= 0 && i < 3)
3107 {
3108 pipe_err = stdio[i].handle = dup(i);
3109 stdio[i].flags = fcntl(i, F_GETFD, 0);
3110 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3111 i++;
3112 }
3113 if (pipe_err < 0)
3114 {
3115 /* didn't get them all saved - clean up and bail out */
3116 int saved_err = errno;
3117 while (i-- > 0)
3118 {
3119 close(stdio[i].handle);
3120 }
3121 errno = saved_err;
3122 return posix_error();
3123 }
3124
3125 /* create pipe ends */
3126 file_count = 2;
3127 if (n == POPEN_3)
3128 file_count = 3;
3129 i = pipe_err = 0;
3130 while ((pipe_err == 0) && (i < file_count))
3131 pipe_err = pipe((int *)&p_fd[i++]);
3132 if (pipe_err < 0)
3133 {
3134 /* didn't get them all made - clean up and bail out */
3135 while (i-- > 0)
3136 {
3137 close(p_fd[i].wr);
3138 close(p_fd[i].rd);
3139 }
3140 errno = EPIPE;
3141 return posix_error();
3142 }
3143
3144 /* change the actual standard IO streams over temporarily,
3145 * making the retained pipe ends non-inheritable
3146 */
3147 pipe_err = 0;
3148
3149 /* - stdin */
3150 if (dup2(p_fd[0].rd, 0) == 0)
3151 {
3152 close(p_fd[0].rd);
3153 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3154 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3155 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3156 {
3157 close(p_fd[0].wr);
3158 pipe_err = -1;
3159 }
3160 }
3161 else
3162 {
3163 pipe_err = -1;
3164 }
3165
3166 /* - stdout */
3167 if (pipe_err == 0)
3168 {
3169 if (dup2(p_fd[1].wr, 1) == 1)
3170 {
3171 close(p_fd[1].wr);
3172 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3173 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3174 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3175 {
3176 close(p_fd[1].rd);
3177 pipe_err = -1;
3178 }
3179 }
3180 else
3181 {
3182 pipe_err = -1;
3183 }
3184 }
3185
3186 /* - stderr, as required */
3187 if (pipe_err == 0)
3188 switch (n)
3189 {
3190 case POPEN_3:
3191 {
3192 if (dup2(p_fd[2].wr, 2) == 2)
3193 {
3194 close(p_fd[2].wr);
3195 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3196 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3197 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3198 {
3199 close(p_fd[2].rd);
3200 pipe_err = -1;
3201 }
3202 }
3203 else
3204 {
3205 pipe_err = -1;
3206 }
3207 break;
3208 }
3209
3210 case POPEN_4:
3211 {
3212 if (dup2(1, 2) != 2)
3213 {
3214 pipe_err = -1;
3215 }
3216 break;
3217 }
3218 }
3219
3220 /* spawn the child process */
3221 if (pipe_err == 0)
3222 {
3223 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3224 if (pipe_pid == -1)
3225 {
3226 pipe_err = -1;
3227 }
3228 else
3229 {
3230 /* save the PID into the FILE structure
3231 * NOTE: this implementation doesn't actually
3232 * take advantage of this, but do it for
3233 * completeness - AIM Apr01
3234 */
3235 for (i = 0; i < file_count; i++)
3236 p_s[i]->_pid = pipe_pid;
3237 }
3238 }
3239
3240 /* reset standard IO to normal */
3241 for (i = 0; i < 3; i++)
3242 {
3243 dup2(stdio[i].handle, i);
3244 fcntl(i, F_SETFD, stdio[i].flags);
3245 close(stdio[i].handle);
3246 }
3247
3248 /* if any remnant problems, clean up and bail out */
3249 if (pipe_err < 0)
3250 {
3251 for (i = 0; i < 3; i++)
3252 {
3253 close(p_fd[i].rd);
3254 close(p_fd[i].wr);
3255 }
3256 errno = EPIPE;
3257 return posix_error_with_filename(cmdstring);
3258 }
3259
3260 /* build tuple of file objects to return */
3261 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3262 PyFile_SetBufSize(p_f[0], bufsize);
3263 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3264 PyFile_SetBufSize(p_f[1], bufsize);
3265 if (n == POPEN_3)
3266 {
3267 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3268 PyFile_SetBufSize(p_f[0], bufsize);
3269 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
3270 }
3271 else
3272 f = Py_BuildValue("OO", p_f[0], p_f[1]);
3273
3274 /*
3275 * Insert the files we've created into the process dictionary
3276 * all referencing the list with the process handle and the
3277 * initial number of files (see description below in _PyPclose).
3278 * Since if _PyPclose later tried to wait on a process when all
3279 * handles weren't closed, it could create a deadlock with the
3280 * child, we spend some energy here to try to ensure that we
3281 * either insert all file handles into the dictionary or none
3282 * at all. It's a little clumsy with the various popen modes
3283 * and variable number of files involved.
3284 */
3285 if (!_PyPopenProcs)
3286 {
3287 _PyPopenProcs = PyDict_New();
3288 }
3289
3290 if (_PyPopenProcs)
3291 {
3292 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3293 int ins_rc[3];
3294
3295 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3296 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3297
3298 procObj = PyList_New(2);
3299 pidObj = PyInt_FromLong((long) pipe_pid);
3300 intObj = PyInt_FromLong((long) file_count);
3301
3302 if (procObj && pidObj && intObj)
3303 {
3304 PyList_SetItem(procObj, 0, pidObj);
3305 PyList_SetItem(procObj, 1, intObj);
3306
3307 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3308 if (fileObj[0])
3309 {
3310 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3311 fileObj[0],
3312 procObj);
3313 }
3314 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3315 if (fileObj[1])
3316 {
3317 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3318 fileObj[1],
3319 procObj);
3320 }
3321 if (file_count >= 3)
3322 {
3323 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3324 if (fileObj[2])
3325 {
3326 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3327 fileObj[2],
3328 procObj);
3329 }
3330 }
3331
3332 if (ins_rc[0] < 0 || !fileObj[0] ||
3333 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3334 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3335 {
3336 /* Something failed - remove any dictionary
3337 * entries that did make it.
3338 */
3339 if (!ins_rc[0] && fileObj[0])
3340 {
3341 PyDict_DelItem(_PyPopenProcs,
3342 fileObj[0]);
3343 }
3344 if (!ins_rc[1] && fileObj[1])
3345 {
3346 PyDict_DelItem(_PyPopenProcs,
3347 fileObj[1]);
3348 }
3349 if (!ins_rc[2] && fileObj[2])
3350 {
3351 PyDict_DelItem(_PyPopenProcs,
3352 fileObj[2]);
3353 }
3354 }
3355 }
3356
3357 /*
3358 * Clean up our localized references for the dictionary keys
3359 * and value since PyDict_SetItem will Py_INCREF any copies
3360 * that got placed in the dictionary.
3361 */
3362 Py_XDECREF(procObj);
3363 Py_XDECREF(fileObj[0]);
3364 Py_XDECREF(fileObj[1]);
3365 Py_XDECREF(fileObj[2]);
3366 }
3367
3368 /* Child is launched. */
3369 return f;
3370}
3371
3372/*
3373 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3374 * exit code for the child process and return as a result of the close.
3375 *
3376 * This function uses the _PyPopenProcs dictionary in order to map the
3377 * input file pointer to information about the process that was
3378 * originally created by the popen* call that created the file pointer.
3379 * The dictionary uses the file pointer as a key (with one entry
3380 * inserted for each file returned by the original popen* call) and a
3381 * single list object as the value for all files from a single call.
3382 * The list object contains the Win32 process handle at [0], and a file
3383 * count at [1], which is initialized to the total number of file
3384 * handles using that list.
3385 *
3386 * This function closes whichever handle it is passed, and decrements
3387 * the file count in the dictionary for the process handle pointed to
3388 * by this file. On the last close (when the file count reaches zero),
3389 * this function will wait for the child process and then return its
3390 * exit code as the result of the close() operation. This permits the
3391 * files to be closed in any order - it is always the close() of the
3392 * final handle that will return the exit code.
3393 */
3394
3395 /* RED_FLAG 31-Aug-2000 Tim
3396 * This is always called (today!) between a pair of
3397 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3398 * macros. So the thread running this has no valid thread state, as
3399 * far as Python is concerned. However, this calls some Python API
3400 * functions that cannot be called safely without a valid thread
3401 * state, in particular PyDict_GetItem.
3402 * As a temporary hack (although it may last for years ...), we
3403 * *rely* on not having a valid thread state in this function, in
3404 * order to create our own "from scratch".
3405 * This will deadlock if _PyPclose is ever called by a thread
3406 * holding the global lock.
3407 * (The OS/2 EMX thread support appears to cover the case where the
3408 * lock is already held - AIM Apr01)
3409 */
3410
3411static int _PyPclose(FILE *file)
3412{
3413 int result;
3414 int exit_code;
3415 int pipe_pid;
3416 PyObject *procObj, *pidObj, *intObj, *fileObj;
3417 int file_count;
3418#ifdef WITH_THREAD
3419 PyInterpreterState* pInterpreterState;
3420 PyThreadState* pThreadState;
3421#endif
3422
3423 /* Close the file handle first, to ensure it can't block the
3424 * child from exiting if it's the last handle.
3425 */
3426 result = fclose(file);
3427
3428#ifdef WITH_THREAD
3429 /* Bootstrap a valid thread state into existence. */
3430 pInterpreterState = PyInterpreterState_New();
3431 if (!pInterpreterState) {
3432 /* Well, we're hosed now! We don't have a thread
3433 * state, so can't call a nice error routine, or raise
3434 * an exception. Just die.
3435 */
3436 Py_FatalError("unable to allocate interpreter state "
3437 "when closing popen object.");
3438 return -1; /* unreachable */
3439 }
3440 pThreadState = PyThreadState_New(pInterpreterState);
3441 if (!pThreadState) {
3442 Py_FatalError("unable to allocate thread state "
3443 "when closing popen object.");
3444 return -1; /* unreachable */
3445 }
3446 /* Grab the global lock. Note that this will deadlock if the
3447 * current thread already has the lock! (see RED_FLAG comments
3448 * before this function)
3449 */
3450 PyEval_RestoreThread(pThreadState);
3451#endif
3452
3453 if (_PyPopenProcs)
3454 {
3455 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3456 (procObj = PyDict_GetItem(_PyPopenProcs,
3457 fileObj)) != NULL &&
3458 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
3459 (intObj = PyList_GetItem(procObj,1)) != NULL)
3460 {
3461 pipe_pid = (int) PyInt_AsLong(pidObj);
3462 file_count = (int) PyInt_AsLong(intObj);
3463
3464 if (file_count > 1)
3465 {
3466 /* Still other files referencing process */
3467 file_count--;
3468 PyList_SetItem(procObj,1,
3469 PyInt_FromLong((long) file_count));
3470 }
3471 else
3472 {
3473 /* Last file for this process */
3474 if (result != EOF &&
3475 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
3476 {
3477 /* extract exit status */
3478 if (WIFEXITED(exit_code))
3479 {
3480 result = WEXITSTATUS(exit_code);
3481 }
3482 else
3483 {
3484 errno = EPIPE;
3485 result = -1;
3486 }
3487 }
3488 else
3489 {
3490 /* Indicate failure - this will cause the file object
3491 * to raise an I/O error and translate the last
3492 * error code from errno. We do have a problem with
3493 * last errors that overlap the normal errno table,
3494 * but that's a consistent problem with the file object.
3495 */
3496 result = -1;
3497 }
3498 }
3499
3500 /* Remove this file pointer from dictionary */
3501 PyDict_DelItem(_PyPopenProcs, fileObj);
3502
3503 if (PyDict_Size(_PyPopenProcs) == 0)
3504 {
3505 Py_DECREF(_PyPopenProcs);
3506 _PyPopenProcs = NULL;
3507 }
3508
3509 } /* if object retrieval ok */
3510
3511 Py_XDECREF(fileObj);
3512 } /* if _PyPopenProcs */
3513
3514#ifdef WITH_THREAD
3515 /* Tear down the thread & interpreter states.
3516 * Note that interpreter state clear & delete functions automatically
3517 * call the thread clear & delete functions, and indeed insist on
3518 * doing that themselves. The lock must be held during the clear, but
3519 * need not be held during the delete.
3520 */
3521 PyInterpreterState_Clear(pInterpreterState);
3522 PyEval_ReleaseThread(pThreadState);
3523 PyInterpreterState_Delete(pInterpreterState);
3524#endif
3525
3526 return result;
3527}
3528
3529#endif /* PYCC_??? */
3530
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003531#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003532
3533/*
3534 * Portable 'popen' replacement for Win32.
3535 *
3536 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3537 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003538 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003539 */
3540
3541#include <malloc.h>
3542#include <io.h>
3543#include <fcntl.h>
3544
3545/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3546#define POPEN_1 1
3547#define POPEN_2 2
3548#define POPEN_3 3
3549#define POPEN_4 4
3550
3551static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003552static int _PyPclose(FILE *file);
3553
3554/*
3555 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003556 * for use when retrieving the process exit code. See _PyPclose() below
3557 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003558 */
3559static PyObject *_PyPopenProcs = NULL;
3560
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003561
3562/* popen that works from a GUI.
3563 *
3564 * The result of this function is a pipe (file) connected to the
3565 * processes stdin or stdout, depending on the requested mode.
3566 */
3567
3568static PyObject *
3569posix_popen(PyObject *self, PyObject *args)
3570{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003571 PyObject *f, *s;
3572 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003573
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003574 char *cmdstring;
3575 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003576 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003577 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003578 return NULL;
3579
3580 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003581
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003582 if (*mode == 'r')
3583 tm = _O_RDONLY;
3584 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003585 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003586 return NULL;
3587 } else
3588 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003589
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003590 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003591 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003592 return NULL;
3593 }
3594
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003595 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003596 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003597 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003598 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003599 else
3600 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3601
3602 return f;
3603}
3604
3605/* Variation on win32pipe.popen
3606 *
3607 * The result of this function is a pipe (file) connected to the
3608 * process's stdin, and a pipe connected to the process's stdout.
3609 */
3610
3611static PyObject *
3612win32_popen2(PyObject *self, PyObject *args)
3613{
3614 PyObject *f;
3615 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003616
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003617 char *cmdstring;
3618 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003619 int bufsize = -1;
3620 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003621 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003622
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003623 if (*mode == 't')
3624 tm = _O_TEXT;
3625 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003626 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003627 return NULL;
3628 } else
3629 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003630
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003631 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003632 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003633 return NULL;
3634 }
3635
3636 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003637
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003638 return f;
3639}
3640
3641/*
3642 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003643 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003644 * The result of this function is 3 pipes - the process's stdin,
3645 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003646 */
3647
3648static PyObject *
3649win32_popen3(PyObject *self, PyObject *args)
3650{
3651 PyObject *f;
3652 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003653
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003654 char *cmdstring;
3655 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003656 int bufsize = -1;
3657 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003658 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003659
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003660 if (*mode == 't')
3661 tm = _O_TEXT;
3662 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003663 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003664 return NULL;
3665 } else
3666 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003667
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003668 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003669 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003670 return NULL;
3671 }
3672
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003673 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003674
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003675 return f;
3676}
3677
3678/*
3679 * Variation on win32pipe.popen
3680 *
Tim Peters5aa91602002-01-30 05:46:57 +00003681 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003682 * and stdout+stderr combined as a single pipe.
3683 */
3684
3685static PyObject *
3686win32_popen4(PyObject *self, PyObject *args)
3687{
3688 PyObject *f;
3689 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003690
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003691 char *cmdstring;
3692 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003693 int bufsize = -1;
3694 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003695 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003696
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003697 if (*mode == 't')
3698 tm = _O_TEXT;
3699 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003700 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003701 return NULL;
3702 } else
3703 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003704
3705 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003706 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003707 return NULL;
3708 }
3709
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003710 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003711
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003712 return f;
3713}
3714
Mark Hammond08501372001-01-31 07:30:29 +00003715static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003716_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003717 HANDLE hStdin,
3718 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003719 HANDLE hStderr,
3720 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003721{
3722 PROCESS_INFORMATION piProcInfo;
3723 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003724 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003725 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003726 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003727 int i;
3728 int x;
3729
3730 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003731 char *comshell;
3732
Tim Peters92e4dd82002-10-05 01:47:34 +00003733 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003734 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3735 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003736
3737 /* Explicitly check if we are using COMMAND.COM. If we are
3738 * then use the w9xpopen hack.
3739 */
3740 comshell = s1 + x;
3741 while (comshell >= s1 && *comshell != '\\')
3742 --comshell;
3743 ++comshell;
3744
3745 if (GetVersion() < 0x80000000 &&
3746 _stricmp(comshell, "command.com") != 0) {
3747 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003748 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00003749 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003750 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003751 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003752 }
3753 else {
3754 /*
Tim Peters402d5982001-08-27 06:37:48 +00003755 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3756 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003757 */
Mark Hammond08501372001-01-31 07:30:29 +00003758 char modulepath[_MAX_PATH];
3759 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003760 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3761 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003762 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003763 x = i+1;
3764 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00003765 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00003766 strncat(modulepath,
3767 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003768 (sizeof(modulepath)/sizeof(modulepath[0]))
3769 -strlen(modulepath));
3770 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003771 /* Eeek - file-not-found - possibly an embedding
3772 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00003773 */
Tim Peters5aa91602002-01-30 05:46:57 +00003774 strncpy(modulepath,
3775 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00003776 sizeof(modulepath)/sizeof(modulepath[0]));
3777 if (modulepath[strlen(modulepath)-1] != '\\')
3778 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00003779 strncat(modulepath,
3780 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003781 (sizeof(modulepath)/sizeof(modulepath[0]))
3782 -strlen(modulepath));
3783 /* No where else to look - raise an easily identifiable
3784 error, rather than leaving Windows to report
3785 "file not found" - as the user is probably blissfully
3786 unaware this shim EXE is used, and it will confuse them.
3787 (well, it confused me for a while ;-)
3788 */
3789 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003790 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00003791 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00003792 "for popen to work with your shell "
3793 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00003794 szConsoleSpawn);
3795 return FALSE;
3796 }
3797 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003798 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00003799 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003800 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00003801
Tim Peters92e4dd82002-10-05 01:47:34 +00003802 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003803 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003804 /* To maintain correct argument passing semantics,
3805 we pass the command-line as it stands, and allow
3806 quoting to be applied. w9xpopen.exe will then
3807 use its argv vector, and re-quote the necessary
3808 args for the ultimate child process.
3809 */
Tim Peters75cdad52001-11-28 22:07:30 +00003810 PyOS_snprintf(
3811 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003812 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003813 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003814 s1,
3815 s3,
3816 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003817 /* Not passing CREATE_NEW_CONSOLE has been known to
3818 cause random failures on win9x. Specifically a
3819 dialog:
3820 "Your program accessed mem currently in use at xxx"
3821 and a hopeful warning about the stability of your
3822 system.
3823 Cost is Ctrl+C wont kill children, but anyone
3824 who cares can have a go!
3825 */
3826 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003827 }
3828 }
3829
3830 /* Could be an else here to try cmd.exe / command.com in the path
3831 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003832 else {
Tim Peters402d5982001-08-27 06:37:48 +00003833 PyErr_SetString(PyExc_RuntimeError,
3834 "Cannot locate a COMSPEC environment variable to "
3835 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00003836 return FALSE;
3837 }
Tim Peters5aa91602002-01-30 05:46:57 +00003838
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003839 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3840 siStartInfo.cb = sizeof(STARTUPINFO);
3841 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3842 siStartInfo.hStdInput = hStdin;
3843 siStartInfo.hStdOutput = hStdout;
3844 siStartInfo.hStdError = hStderr;
3845 siStartInfo.wShowWindow = SW_HIDE;
3846
3847 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003848 s2,
3849 NULL,
3850 NULL,
3851 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003852 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003853 NULL,
3854 NULL,
3855 &siStartInfo,
3856 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003857 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003858 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003859
Mark Hammondb37a3732000-08-14 04:47:33 +00003860 /* Return process handle */
3861 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003862 return TRUE;
3863 }
Tim Peters402d5982001-08-27 06:37:48 +00003864 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003865 return FALSE;
3866}
3867
3868/* The following code is based off of KB: Q190351 */
3869
3870static PyObject *
3871_PyPopen(char *cmdstring, int mode, int n)
3872{
3873 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
3874 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00003875 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00003876
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003877 SECURITY_ATTRIBUTES saAttr;
3878 BOOL fSuccess;
3879 int fd1, fd2, fd3;
3880 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00003881 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003882 PyObject *f;
3883
3884 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
3885 saAttr.bInheritHandle = TRUE;
3886 saAttr.lpSecurityDescriptor = NULL;
3887
3888 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
3889 return win32_error("CreatePipe", NULL);
3890
3891 /* Create new output read handle and the input write handle. Set
3892 * the inheritance properties to FALSE. Otherwise, the child inherits
3893 * the these handles; resulting in non-closeable handles to the pipes
3894 * being created. */
3895 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003896 GetCurrentProcess(), &hChildStdinWrDup, 0,
3897 FALSE,
3898 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003899 if (!fSuccess)
3900 return win32_error("DuplicateHandle", NULL);
3901
3902 /* Close the inheritable version of ChildStdin
3903 that we're using. */
3904 CloseHandle(hChildStdinWr);
3905
3906 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
3907 return win32_error("CreatePipe", NULL);
3908
3909 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003910 GetCurrentProcess(), &hChildStdoutRdDup, 0,
3911 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003912 if (!fSuccess)
3913 return win32_error("DuplicateHandle", NULL);
3914
3915 /* Close the inheritable version of ChildStdout
3916 that we're using. */
3917 CloseHandle(hChildStdoutRd);
3918
3919 if (n != POPEN_4) {
3920 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
3921 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003922 fSuccess = DuplicateHandle(GetCurrentProcess(),
3923 hChildStderrRd,
3924 GetCurrentProcess(),
3925 &hChildStderrRdDup, 0,
3926 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003927 if (!fSuccess)
3928 return win32_error("DuplicateHandle", NULL);
3929 /* Close the inheritable version of ChildStdErr that we're using. */
3930 CloseHandle(hChildStderrRd);
3931 }
Tim Peters5aa91602002-01-30 05:46:57 +00003932
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003933 switch (n) {
3934 case POPEN_1:
3935 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
3936 case _O_WRONLY | _O_TEXT:
3937 /* Case for writing to child Stdin in text mode. */
3938 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3939 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003940 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003941 PyFile_SetBufSize(f, 0);
3942 /* We don't care about these pipes anymore, so close them. */
3943 CloseHandle(hChildStdoutRdDup);
3944 CloseHandle(hChildStderrRdDup);
3945 break;
3946
3947 case _O_RDONLY | _O_TEXT:
3948 /* Case for reading from child Stdout in text mode. */
3949 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3950 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003951 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003952 PyFile_SetBufSize(f, 0);
3953 /* We don't care about these pipes anymore, so close them. */
3954 CloseHandle(hChildStdinWrDup);
3955 CloseHandle(hChildStderrRdDup);
3956 break;
3957
3958 case _O_RDONLY | _O_BINARY:
3959 /* Case for readinig from child Stdout in binary mode. */
3960 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3961 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003962 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003963 PyFile_SetBufSize(f, 0);
3964 /* We don't care about these pipes anymore, so close them. */
3965 CloseHandle(hChildStdinWrDup);
3966 CloseHandle(hChildStderrRdDup);
3967 break;
3968
3969 case _O_WRONLY | _O_BINARY:
3970 /* Case for writing to child Stdin in binary mode. */
3971 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3972 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003973 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003974 PyFile_SetBufSize(f, 0);
3975 /* We don't care about these pipes anymore, so close them. */
3976 CloseHandle(hChildStdoutRdDup);
3977 CloseHandle(hChildStderrRdDup);
3978 break;
3979 }
Mark Hammondb37a3732000-08-14 04:47:33 +00003980 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003981 break;
Tim Peters5aa91602002-01-30 05:46:57 +00003982
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003983 case POPEN_2:
3984 case POPEN_4:
3985 {
3986 char *m1, *m2;
3987 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00003988
Tim Peters7dca21e2002-08-19 00:42:29 +00003989 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003990 m1 = "r";
3991 m2 = "w";
3992 } else {
3993 m1 = "rb";
3994 m2 = "wb";
3995 }
3996
3997 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3998 f1 = _fdopen(fd1, m2);
3999 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4000 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004001 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004002 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004003 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004004 PyFile_SetBufSize(p2, 0);
4005
4006 if (n != 4)
4007 CloseHandle(hChildStderrRdDup);
4008
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004009 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004010 Py_XDECREF(p1);
4011 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004012 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004013 break;
4014 }
Tim Peters5aa91602002-01-30 05:46:57 +00004015
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004016 case POPEN_3:
4017 {
4018 char *m1, *m2;
4019 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004020
Tim Peters7dca21e2002-08-19 00:42:29 +00004021 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004022 m1 = "r";
4023 m2 = "w";
4024 } else {
4025 m1 = "rb";
4026 m2 = "wb";
4027 }
4028
4029 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4030 f1 = _fdopen(fd1, m2);
4031 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4032 f2 = _fdopen(fd2, m1);
4033 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
4034 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004035 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004036 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4037 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004038 PyFile_SetBufSize(p1, 0);
4039 PyFile_SetBufSize(p2, 0);
4040 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004041 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004042 Py_XDECREF(p1);
4043 Py_XDECREF(p2);
4044 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004045 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004046 break;
4047 }
4048 }
4049
4050 if (n == POPEN_4) {
4051 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004052 hChildStdinRd,
4053 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004054 hChildStdoutWr,
4055 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004056 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004057 }
4058 else {
4059 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004060 hChildStdinRd,
4061 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004062 hChildStderrWr,
4063 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004064 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004065 }
4066
Mark Hammondb37a3732000-08-14 04:47:33 +00004067 /*
4068 * Insert the files we've created into the process dictionary
4069 * all referencing the list with the process handle and the
4070 * initial number of files (see description below in _PyPclose).
4071 * Since if _PyPclose later tried to wait on a process when all
4072 * handles weren't closed, it could create a deadlock with the
4073 * child, we spend some energy here to try to ensure that we
4074 * either insert all file handles into the dictionary or none
4075 * at all. It's a little clumsy with the various popen modes
4076 * and variable number of files involved.
4077 */
4078 if (!_PyPopenProcs) {
4079 _PyPopenProcs = PyDict_New();
4080 }
4081
4082 if (_PyPopenProcs) {
4083 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4084 int ins_rc[3];
4085
4086 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4087 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4088
4089 procObj = PyList_New(2);
4090 hProcessObj = PyLong_FromVoidPtr(hProcess);
4091 intObj = PyInt_FromLong(file_count);
4092
4093 if (procObj && hProcessObj && intObj) {
4094 PyList_SetItem(procObj,0,hProcessObj);
4095 PyList_SetItem(procObj,1,intObj);
4096
4097 fileObj[0] = PyLong_FromVoidPtr(f1);
4098 if (fileObj[0]) {
4099 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4100 fileObj[0],
4101 procObj);
4102 }
4103 if (file_count >= 2) {
4104 fileObj[1] = PyLong_FromVoidPtr(f2);
4105 if (fileObj[1]) {
4106 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4107 fileObj[1],
4108 procObj);
4109 }
4110 }
4111 if (file_count >= 3) {
4112 fileObj[2] = PyLong_FromVoidPtr(f3);
4113 if (fileObj[2]) {
4114 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4115 fileObj[2],
4116 procObj);
4117 }
4118 }
4119
4120 if (ins_rc[0] < 0 || !fileObj[0] ||
4121 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4122 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4123 /* Something failed - remove any dictionary
4124 * entries that did make it.
4125 */
4126 if (!ins_rc[0] && fileObj[0]) {
4127 PyDict_DelItem(_PyPopenProcs,
4128 fileObj[0]);
4129 }
4130 if (!ins_rc[1] && fileObj[1]) {
4131 PyDict_DelItem(_PyPopenProcs,
4132 fileObj[1]);
4133 }
4134 if (!ins_rc[2] && fileObj[2]) {
4135 PyDict_DelItem(_PyPopenProcs,
4136 fileObj[2]);
4137 }
4138 }
4139 }
Tim Peters5aa91602002-01-30 05:46:57 +00004140
Mark Hammondb37a3732000-08-14 04:47:33 +00004141 /*
4142 * Clean up our localized references for the dictionary keys
4143 * and value since PyDict_SetItem will Py_INCREF any copies
4144 * that got placed in the dictionary.
4145 */
4146 Py_XDECREF(procObj);
4147 Py_XDECREF(fileObj[0]);
4148 Py_XDECREF(fileObj[1]);
4149 Py_XDECREF(fileObj[2]);
4150 }
4151
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004152 /* Child is launched. Close the parents copy of those pipe
4153 * handles that only the child should have open. You need to
4154 * make sure that no handles to the write end of the output pipe
4155 * are maintained in this process or else the pipe will not close
4156 * when the child process exits and the ReadFile will hang. */
4157
4158 if (!CloseHandle(hChildStdinRd))
4159 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004160
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004161 if (!CloseHandle(hChildStdoutWr))
4162 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004163
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004164 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4165 return win32_error("CloseHandle", NULL);
4166
4167 return f;
4168}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004169
4170/*
4171 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4172 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004173 *
4174 * This function uses the _PyPopenProcs dictionary in order to map the
4175 * input file pointer to information about the process that was
4176 * originally created by the popen* call that created the file pointer.
4177 * The dictionary uses the file pointer as a key (with one entry
4178 * inserted for each file returned by the original popen* call) and a
4179 * single list object as the value for all files from a single call.
4180 * The list object contains the Win32 process handle at [0], and a file
4181 * count at [1], which is initialized to the total number of file
4182 * handles using that list.
4183 *
4184 * This function closes whichever handle it is passed, and decrements
4185 * the file count in the dictionary for the process handle pointed to
4186 * by this file. On the last close (when the file count reaches zero),
4187 * this function will wait for the child process and then return its
4188 * exit code as the result of the close() operation. This permits the
4189 * files to be closed in any order - it is always the close() of the
4190 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004191 */
Tim Peters736aa322000-09-01 06:51:24 +00004192
4193 /* RED_FLAG 31-Aug-2000 Tim
4194 * This is always called (today!) between a pair of
4195 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
4196 * macros. So the thread running this has no valid thread state, as
4197 * far as Python is concerned. However, this calls some Python API
4198 * functions that cannot be called safely without a valid thread
4199 * state, in particular PyDict_GetItem.
4200 * As a temporary hack (although it may last for years ...), we
4201 * *rely* on not having a valid thread state in this function, in
4202 * order to create our own "from scratch".
4203 * This will deadlock if _PyPclose is ever called by a thread
4204 * holding the global lock.
4205 */
4206
Fredrik Lundh56055a42000-07-23 19:47:12 +00004207static int _PyPclose(FILE *file)
4208{
Fredrik Lundh20318932000-07-26 17:29:12 +00004209 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004210 DWORD exit_code;
4211 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004212 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4213 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004214#ifdef WITH_THREAD
4215 PyInterpreterState* pInterpreterState;
4216 PyThreadState* pThreadState;
4217#endif
4218
Fredrik Lundh20318932000-07-26 17:29:12 +00004219 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004220 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004221 */
4222 result = fclose(file);
4223
Tim Peters736aa322000-09-01 06:51:24 +00004224#ifdef WITH_THREAD
4225 /* Bootstrap a valid thread state into existence. */
4226 pInterpreterState = PyInterpreterState_New();
4227 if (!pInterpreterState) {
4228 /* Well, we're hosed now! We don't have a thread
4229 * state, so can't call a nice error routine, or raise
4230 * an exception. Just die.
4231 */
4232 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00004233 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00004234 return -1; /* unreachable */
4235 }
4236 pThreadState = PyThreadState_New(pInterpreterState);
4237 if (!pThreadState) {
4238 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00004239 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00004240 return -1; /* unreachable */
4241 }
4242 /* Grab the global lock. Note that this will deadlock if the
4243 * current thread already has the lock! (see RED_FLAG comments
4244 * before this function)
4245 */
4246 PyEval_RestoreThread(pThreadState);
4247#endif
4248
Fredrik Lundh56055a42000-07-23 19:47:12 +00004249 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004250 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4251 (procObj = PyDict_GetItem(_PyPopenProcs,
4252 fileObj)) != NULL &&
4253 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4254 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4255
4256 hProcess = PyLong_AsVoidPtr(hProcessObj);
4257 file_count = PyInt_AsLong(intObj);
4258
4259 if (file_count > 1) {
4260 /* Still other files referencing process */
4261 file_count--;
4262 PyList_SetItem(procObj,1,
4263 PyInt_FromLong(file_count));
4264 } else {
4265 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004266 if (result != EOF &&
4267 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4268 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004269 /* Possible truncation here in 16-bit environments, but
4270 * real exit codes are just the lower byte in any event.
4271 */
4272 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004273 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004274 /* Indicate failure - this will cause the file object
4275 * to raise an I/O error and translate the last Win32
4276 * error code from errno. We do have a problem with
4277 * last errors that overlap the normal errno table,
4278 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004279 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004280 if (result != EOF) {
4281 /* If the error wasn't from the fclose(), then
4282 * set errno for the file object error handling.
4283 */
4284 errno = GetLastError();
4285 }
4286 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004287 }
4288
4289 /* Free up the native handle at this point */
4290 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004291 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004292
Mark Hammondb37a3732000-08-14 04:47:33 +00004293 /* Remove this file pointer from dictionary */
4294 PyDict_DelItem(_PyPopenProcs, fileObj);
4295
4296 if (PyDict_Size(_PyPopenProcs) == 0) {
4297 Py_DECREF(_PyPopenProcs);
4298 _PyPopenProcs = NULL;
4299 }
4300
4301 } /* if object retrieval ok */
4302
4303 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004304 } /* if _PyPopenProcs */
4305
Tim Peters736aa322000-09-01 06:51:24 +00004306#ifdef WITH_THREAD
4307 /* Tear down the thread & interpreter states.
4308 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00004309 * call the thread clear & delete functions, and indeed insist on
4310 * doing that themselves. The lock must be held during the clear, but
4311 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00004312 */
4313 PyInterpreterState_Clear(pInterpreterState);
4314 PyEval_ReleaseThread(pThreadState);
4315 PyInterpreterState_Delete(pInterpreterState);
4316#endif
4317
Fredrik Lundh56055a42000-07-23 19:47:12 +00004318 return result;
4319}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004320
4321#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004322static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004323posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004324{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004325 char *name;
4326 char *mode = "r";
4327 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004328 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004329 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004330 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004331 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004332 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004333 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004334 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004335 if (fp == NULL)
4336 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004337 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004338 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004339 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004340 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004341}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004342
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004343#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004344#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004345
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004346
Guido van Rossumb6775db1994-08-01 11:34:53 +00004347#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004348PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004349"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004350Set the current process's user id.");
4351
Barry Warsaw53699e91996-12-10 23:23:01 +00004352static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004353posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004354{
4355 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004356 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004357 return NULL;
4358 if (setuid(uid) < 0)
4359 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004360 Py_INCREF(Py_None);
4361 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004362}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004363#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004364
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004365
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004366#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004367PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004368"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004369Set the current process's effective user id.");
4370
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004371static PyObject *
4372posix_seteuid (PyObject *self, PyObject *args)
4373{
4374 int euid;
4375 if (!PyArg_ParseTuple(args, "i", &euid)) {
4376 return NULL;
4377 } else if (seteuid(euid) < 0) {
4378 return posix_error();
4379 } else {
4380 Py_INCREF(Py_None);
4381 return Py_None;
4382 }
4383}
4384#endif /* HAVE_SETEUID */
4385
4386#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004387PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004388"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004389Set the current process's effective group id.");
4390
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004391static PyObject *
4392posix_setegid (PyObject *self, PyObject *args)
4393{
4394 int egid;
4395 if (!PyArg_ParseTuple(args, "i", &egid)) {
4396 return NULL;
4397 } else if (setegid(egid) < 0) {
4398 return posix_error();
4399 } else {
4400 Py_INCREF(Py_None);
4401 return Py_None;
4402 }
4403}
4404#endif /* HAVE_SETEGID */
4405
4406#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004407PyDoc_STRVAR(posix_setreuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004408"seteuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004409Set the current process's real and effective user ids.");
4410
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004411static PyObject *
4412posix_setreuid (PyObject *self, PyObject *args)
4413{
4414 int ruid, euid;
4415 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4416 return NULL;
4417 } else if (setreuid(ruid, euid) < 0) {
4418 return posix_error();
4419 } else {
4420 Py_INCREF(Py_None);
4421 return Py_None;
4422 }
4423}
4424#endif /* HAVE_SETREUID */
4425
4426#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004427PyDoc_STRVAR(posix_setregid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004428"setegid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004429Set the current process's real and effective group ids.");
4430
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004431static PyObject *
4432posix_setregid (PyObject *self, PyObject *args)
4433{
4434 int rgid, egid;
4435 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4436 return NULL;
4437 } else if (setregid(rgid, egid) < 0) {
4438 return posix_error();
4439 } else {
4440 Py_INCREF(Py_None);
4441 return Py_None;
4442 }
4443}
4444#endif /* HAVE_SETREGID */
4445
Guido van Rossumb6775db1994-08-01 11:34:53 +00004446#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004447PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004448"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004449Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004450
Barry Warsaw53699e91996-12-10 23:23:01 +00004451static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004452posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004453{
4454 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004455 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004456 return NULL;
4457 if (setgid(gid) < 0)
4458 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004459 Py_INCREF(Py_None);
4460 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004461}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004462#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004463
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004464#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004465PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004466"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004467Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004468
4469static PyObject *
4470posix_setgroups(PyObject *self, PyObject *args)
4471{
4472 PyObject *groups;
4473 int i, len;
4474 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004475
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004476 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4477 return NULL;
4478 if (!PySequence_Check(groups)) {
4479 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4480 return NULL;
4481 }
4482 len = PySequence_Size(groups);
4483 if (len > MAX_GROUPS) {
4484 PyErr_SetString(PyExc_ValueError, "too many groups");
4485 return NULL;
4486 }
4487 for(i = 0; i < len; i++) {
4488 PyObject *elem;
4489 elem = PySequence_GetItem(groups, i);
4490 if (!elem)
4491 return NULL;
4492 if (!PyInt_Check(elem)) {
4493 PyErr_SetString(PyExc_TypeError,
4494 "groups must be integers");
4495 Py_DECREF(elem);
4496 return NULL;
4497 }
4498 /* XXX: check that value fits into gid_t. */
4499 grouplist[i] = PyInt_AsLong(elem);
4500 Py_DECREF(elem);
4501 }
4502
4503 if (setgroups(len, grouplist) < 0)
4504 return posix_error();
4505 Py_INCREF(Py_None);
4506 return Py_None;
4507}
4508#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004509
Guido van Rossumb6775db1994-08-01 11:34:53 +00004510#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004511PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004512"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004513Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004514
Barry Warsaw53699e91996-12-10 23:23:01 +00004515static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004516posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004517{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004518 int pid, options;
4519#ifdef UNION_WAIT
4520 union wait status;
4521#define status_i (status.w_status)
4522#else
4523 int status;
4524#define status_i status
4525#endif
4526 status_i = 0;
4527
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004528 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004529 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004530 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004531 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004532 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004533 if (pid == -1)
4534 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004535 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004536 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004537}
4538
Tim Petersab034fa2002-02-01 11:27:43 +00004539#elif defined(HAVE_CWAIT)
4540
4541/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004542PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004543"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004544"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004545
4546static PyObject *
4547posix_waitpid(PyObject *self, PyObject *args)
4548{
4549 int pid, options;
4550 int status;
4551
4552 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4553 return NULL;
4554 Py_BEGIN_ALLOW_THREADS
4555 pid = _cwait(&status, pid, options);
4556 Py_END_ALLOW_THREADS
4557 if (pid == -1)
4558 return posix_error();
4559 else
4560 /* shift the status left a byte so this is more like the
4561 POSIX waitpid */
4562 return Py_BuildValue("ii", pid, status << 8);
4563}
4564#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004565
Guido van Rossumad0ee831995-03-01 10:34:45 +00004566#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004567PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004568"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004569Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004570
Barry Warsaw53699e91996-12-10 23:23:01 +00004571static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004572posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00004573{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004574 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004575#ifdef UNION_WAIT
4576 union wait status;
4577#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004578#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004579 int status;
4580#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004581#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004582 if (!PyArg_ParseTuple(args, ":wait"))
4583 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004584 status_i = 0;
4585 Py_BEGIN_ALLOW_THREADS
4586 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004587 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004588 if (pid == -1)
4589 return posix_error();
4590 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004591 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004592#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004593}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004594#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004595
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004596
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004597PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004598"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004599Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004600
Barry Warsaw53699e91996-12-10 23:23:01 +00004601static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004602posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004603{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004604#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004605 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004606#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004607#ifdef MS_WINDOWS
4608 return posix_do_stat(self, args, "et:lstat", STAT, "u:lstat", _wstati64);
4609#else
4610 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4611#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004612#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004613}
4614
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004615
Guido van Rossumb6775db1994-08-01 11:34:53 +00004616#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004617PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004618"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004619Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004620
Barry Warsaw53699e91996-12-10 23:23:01 +00004621static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004622posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004623{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004624 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004625 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004626 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004627 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004628 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004629 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004630 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004631 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004632 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004633 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004634 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004635}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004636#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004637
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004638
Guido van Rossumb6775db1994-08-01 11:34:53 +00004639#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004640PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004641"symlink(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004642Create a symbolic link.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004643
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004644static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004645posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004646{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004647 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004648}
4649#endif /* HAVE_SYMLINK */
4650
4651
4652#ifdef HAVE_TIMES
4653#ifndef HZ
4654#define HZ 60 /* Universal constant :-) */
4655#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004656
Guido van Rossumd48f2521997-12-05 22:19:34 +00004657#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4658static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004659system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004660{
4661 ULONG value = 0;
4662
4663 Py_BEGIN_ALLOW_THREADS
4664 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4665 Py_END_ALLOW_THREADS
4666
4667 return value;
4668}
4669
4670static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004671posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004672{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004673 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00004674 return NULL;
4675
4676 /* Currently Only Uptime is Provided -- Others Later */
4677 return Py_BuildValue("ddddd",
4678 (double)0 /* t.tms_utime / HZ */,
4679 (double)0 /* t.tms_stime / HZ */,
4680 (double)0 /* t.tms_cutime / HZ */,
4681 (double)0 /* t.tms_cstime / HZ */,
4682 (double)system_uptime() / 1000);
4683}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004684#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004685static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004686posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004687{
4688 struct tms t;
4689 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004690 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00004691 return NULL;
4692 errno = 0;
4693 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004694 if (c == (clock_t) -1)
4695 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004696 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004697 (double)t.tms_utime / HZ,
4698 (double)t.tms_stime / HZ,
4699 (double)t.tms_cutime / HZ,
4700 (double)t.tms_cstime / HZ,
4701 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004702}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004703#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004704#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004705
4706
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004707#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004708#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004709static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004710posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004711{
4712 FILETIME create, exit, kernel, user;
4713 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004714 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004715 return NULL;
4716 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004717 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4718 /* The fields of a FILETIME structure are the hi and lo part
4719 of a 64-bit value expressed in 100 nanosecond units.
4720 1e7 is one second in such units; 1e-7 the inverse.
4721 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4722 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004723 return Py_BuildValue(
4724 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004725 (double)(kernel.dwHighDateTime*429.4967296 +
4726 kernel.dwLowDateTime*1e-7),
4727 (double)(user.dwHighDateTime*429.4967296 +
4728 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004729 (double)0,
4730 (double)0,
4731 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004732}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004733#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004734
4735#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004736PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004737"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004738Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004739#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004740
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004741
Guido van Rossumb6775db1994-08-01 11:34:53 +00004742#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004743PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004744"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004745Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004746
Barry Warsaw53699e91996-12-10 23:23:01 +00004747static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004748posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004749{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004750 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004751 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004752 if (setsid() < 0)
4753 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004754 Py_INCREF(Py_None);
4755 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004756}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004757#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004758
Guido van Rossumb6775db1994-08-01 11:34:53 +00004759#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004760PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004761"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004762Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004763
Barry Warsaw53699e91996-12-10 23:23:01 +00004764static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004765posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004766{
4767 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004768 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004769 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004770 if (setpgid(pid, pgrp) < 0)
4771 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004772 Py_INCREF(Py_None);
4773 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004774}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004775#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004776
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004777
Guido van Rossumb6775db1994-08-01 11:34:53 +00004778#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004779PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004780"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004781Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004782
Barry Warsaw53699e91996-12-10 23:23:01 +00004783static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004784posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004785{
4786 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004787 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004788 return NULL;
4789 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004790 if (pgid < 0)
4791 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004792 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004793}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004794#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004795
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004796
Guido van Rossumb6775db1994-08-01 11:34:53 +00004797#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004798PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004799"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004800Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004801
Barry Warsaw53699e91996-12-10 23:23:01 +00004802static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004803posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004804{
4805 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004806 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004807 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004808 if (tcsetpgrp(fd, pgid) < 0)
4809 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004810 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004811 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004812}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004813#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004814
Guido van Rossum687dd131993-05-17 08:34:16 +00004815/* Functions acting on file descriptors */
4816
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004817PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004818"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004819Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004820
Barry Warsaw53699e91996-12-10 23:23:01 +00004821static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004822posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004823{
Mark Hammondef8b6542001-05-13 08:04:26 +00004824 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004825 int flag;
4826 int mode = 0777;
4827 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004828
4829#ifdef MS_WINDOWS
4830 if (unicode_file_names()) {
4831 PyUnicodeObject *po;
4832 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4833 Py_BEGIN_ALLOW_THREADS
4834 /* PyUnicode_AS_UNICODE OK without thread
4835 lock as it is a simple dereference. */
4836 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4837 Py_END_ALLOW_THREADS
4838 if (fd < 0)
4839 return posix_error();
4840 return PyInt_FromLong((long)fd);
4841 }
4842 /* Drop the argument parsing error as narrow strings
4843 are also valid. */
4844 PyErr_Clear();
4845 }
4846#endif
4847
Tim Peters5aa91602002-01-30 05:46:57 +00004848 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004849 Py_FileSystemDefaultEncoding, &file,
4850 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004851 return NULL;
4852
Barry Warsaw53699e91996-12-10 23:23:01 +00004853 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004854 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004855 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004856 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004857 return posix_error_with_allocated_filename(file);
4858 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004859 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004860}
4861
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004862
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004863PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004864"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004865Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004866
Barry Warsaw53699e91996-12-10 23:23:01 +00004867static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004868posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004869{
4870 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004871 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004872 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004873 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004874 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004875 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004876 if (res < 0)
4877 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004878 Py_INCREF(Py_None);
4879 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004880}
4881
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004882
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004883PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004884"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004885Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004886
Barry Warsaw53699e91996-12-10 23:23:01 +00004887static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004888posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004889{
4890 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004891 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004892 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004893 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004894 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004895 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004896 if (fd < 0)
4897 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004898 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004899}
4900
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004901
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004902PyDoc_STRVAR(posix_dup2__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004903"dup2(fd, fd2)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004904Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004905
Barry Warsaw53699e91996-12-10 23:23:01 +00004906static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004907posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004908{
4909 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004910 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004911 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004912 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004913 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004914 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004915 if (res < 0)
4916 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004917 Py_INCREF(Py_None);
4918 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004919}
4920
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004921
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004922PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004923"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004924Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004925
Barry Warsaw53699e91996-12-10 23:23:01 +00004926static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004927posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004928{
4929 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004930#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004931 LONG_LONG pos, res;
4932#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004933 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004934#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004935 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004936 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004937 return NULL;
4938#ifdef SEEK_SET
4939 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4940 switch (how) {
4941 case 0: how = SEEK_SET; break;
4942 case 1: how = SEEK_CUR; break;
4943 case 2: how = SEEK_END; break;
4944 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004945#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004946
4947#if !defined(HAVE_LARGEFILE_SUPPORT)
4948 pos = PyInt_AsLong(posobj);
4949#else
4950 pos = PyLong_Check(posobj) ?
4951 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4952#endif
4953 if (PyErr_Occurred())
4954 return NULL;
4955
Barry Warsaw53699e91996-12-10 23:23:01 +00004956 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004957#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004958 res = _lseeki64(fd, pos, how);
4959#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004960 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004961#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004962 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004963 if (res < 0)
4964 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004965
4966#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00004967 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004968#else
4969 return PyLong_FromLongLong(res);
4970#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004971}
4972
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004973
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004974PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004975"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004976Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004977
Barry Warsaw53699e91996-12-10 23:23:01 +00004978static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004979posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004980{
Guido van Rossum8bac5461996-06-11 18:38:48 +00004981 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004982 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004983 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004984 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004985 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004986 if (buffer == NULL)
4987 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004988 Py_BEGIN_ALLOW_THREADS
4989 n = read(fd, PyString_AsString(buffer), size);
4990 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004991 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004992 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004993 return posix_error();
4994 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004995 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00004996 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004997 return buffer;
4998}
4999
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005000
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005001PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005002"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005003Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005004
Barry Warsaw53699e91996-12-10 23:23:01 +00005005static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005006posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005007{
5008 int fd, size;
5009 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005010 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005011 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005012 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005013 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005014 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005015 if (size < 0)
5016 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005017 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005018}
5019
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005020
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005021PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005022"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005023Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005024
Barry Warsaw53699e91996-12-10 23:23:01 +00005025static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005026posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005027{
5028 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005029 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005030 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005031 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005032 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005033 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005034 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005035 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005036 if (res != 0)
5037 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00005038
Fred Drake699f3522000-06-29 21:12:41 +00005039 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005040}
5041
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005042
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005043PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005044"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005045Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005046
Barry Warsaw53699e91996-12-10 23:23:01 +00005047static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005048posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005049{
Guido van Rossum687dd131993-05-17 08:34:16 +00005050 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005051 char *mode = "r";
5052 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005053 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005054 PyObject *f;
5055 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005056 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005057
Thomas Heller1f043e22002-11-07 16:00:59 +00005058 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5059 PyErr_Format(PyExc_ValueError,
5060 "invalid file mode '%s'", mode);
5061 return NULL;
5062 }
5063
Barry Warsaw53699e91996-12-10 23:23:01 +00005064 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005065 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005066 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005067 if (fp == NULL)
5068 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005069 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005070 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005071 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005072 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005073}
5074
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005075PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005076"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005077Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005078connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005079
5080static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005081posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005082{
5083 int fd;
5084 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5085 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005086 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005087}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005088
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005089#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005090PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005091"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005092Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005093
Barry Warsaw53699e91996-12-10 23:23:01 +00005094static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005095posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005096{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005097#if defined(PYOS_OS2)
5098 HFILE read, write;
5099 APIRET rc;
5100
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005101 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005102 return NULL;
5103
5104 Py_BEGIN_ALLOW_THREADS
5105 rc = DosCreatePipe( &read, &write, 4096);
5106 Py_END_ALLOW_THREADS
5107 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005108 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005109
5110 return Py_BuildValue("(ii)", read, write);
5111#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005112#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005113 int fds[2];
5114 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005115 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00005116 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005117 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005118 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005119 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005120 if (res != 0)
5121 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005122 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005123#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005124 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005125 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005126 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005127 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00005128 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005129 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005130 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005131 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005132 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005133 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005134 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5135 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005136 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005137#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005138#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005139}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005140#endif /* HAVE_PIPE */
5141
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005142
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005143#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005144PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005145"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005146Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005147
Barry Warsaw53699e91996-12-10 23:23:01 +00005148static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005149posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005150{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005151 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005152 int mode = 0666;
5153 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005154 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005155 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005156 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005157 res = mkfifo(filename, mode);
5158 Py_END_ALLOW_THREADS
5159 if (res < 0)
5160 return posix_error();
5161 Py_INCREF(Py_None);
5162 return Py_None;
5163}
5164#endif
5165
5166
Neal Norwitz11690112002-07-30 01:08:28 +00005167#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005168PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005169"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005170Create a filesystem node (file, device special file or named pipe)\n\
5171named filename. mode specifies both the permissions to use and the\n\
5172type of node to be created, being combined (bitwise OR) with one of\n\
5173S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005174device defines the newly created device special file (probably using\n\
5175os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005176
5177
5178static PyObject *
5179posix_mknod(PyObject *self, PyObject *args)
5180{
5181 char *filename;
5182 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005183 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005184 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005185 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005186 return NULL;
5187 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005188 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005189 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005190 if (res < 0)
5191 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005192 Py_INCREF(Py_None);
5193 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005194}
5195#endif
5196
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005197#ifdef HAVE_DEVICE_MACROS
5198PyDoc_STRVAR(posix_major__doc__,
5199"major(device) -> major number\n\
5200Extracts a device major number from a raw device number.");
5201
5202static PyObject *
5203posix_major(PyObject *self, PyObject *args)
5204{
5205 int device;
5206 if (!PyArg_ParseTuple(args, "i:major", &device))
5207 return NULL;
5208 return PyInt_FromLong((long)major(device));
5209}
5210
5211PyDoc_STRVAR(posix_minor__doc__,
5212"minor(device) -> minor number\n\
5213Extracts a device minor number from a raw device number.");
5214
5215static PyObject *
5216posix_minor(PyObject *self, PyObject *args)
5217{
5218 int device;
5219 if (!PyArg_ParseTuple(args, "i:minor", &device))
5220 return NULL;
5221 return PyInt_FromLong((long)minor(device));
5222}
5223
5224PyDoc_STRVAR(posix_makedev__doc__,
5225"makedev(major, minor) -> device number\n\
5226Composes a raw device number from the major and minor device numbers.");
5227
5228static PyObject *
5229posix_makedev(PyObject *self, PyObject *args)
5230{
5231 int major, minor;
5232 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5233 return NULL;
5234 return PyInt_FromLong((long)makedev(major, minor));
5235}
5236#endif /* device macros */
5237
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005238
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005239#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005240PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005241"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005242Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005243
Barry Warsaw53699e91996-12-10 23:23:01 +00005244static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005245posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005246{
5247 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005248 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005249 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005250 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005251
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005252 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005253 return NULL;
5254
5255#if !defined(HAVE_LARGEFILE_SUPPORT)
5256 length = PyInt_AsLong(lenobj);
5257#else
5258 length = PyLong_Check(lenobj) ?
5259 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5260#endif
5261 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005262 return NULL;
5263
Barry Warsaw53699e91996-12-10 23:23:01 +00005264 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005265 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005266 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005267 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005268 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005269 return NULL;
5270 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005271 Py_INCREF(Py_None);
5272 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005273}
5274#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005275
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005276#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005277PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005278"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005279Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005280
Fred Drake762e2061999-08-26 17:23:54 +00005281/* Save putenv() parameters as values here, so we can collect them when they
5282 * get re-set with another call for the same key. */
5283static PyObject *posix_putenv_garbage;
5284
Tim Peters5aa91602002-01-30 05:46:57 +00005285static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005286posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005287{
5288 char *s1, *s2;
5289 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005290 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005291 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005292
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005293 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005294 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005295
5296#if defined(PYOS_OS2)
5297 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5298 APIRET rc;
5299
5300 if (strlen(s2) == 0) /* If New Value is an Empty String */
5301 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
5302
5303 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5304 if (rc != NO_ERROR)
5305 return os2_error(rc);
5306
5307 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5308 APIRET rc;
5309
5310 if (strlen(s2) == 0) /* If New Value is an Empty String */
5311 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
5312
5313 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5314 if (rc != NO_ERROR)
5315 return os2_error(rc);
5316 } else {
5317#endif
5318
Fred Drake762e2061999-08-26 17:23:54 +00005319 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005320 len = strlen(s1) + strlen(s2) + 2;
5321 /* len includes space for a trailing \0; the size arg to
5322 PyString_FromStringAndSize does not count that */
5323 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005324 if (newstr == NULL)
5325 return PyErr_NoMemory();
5326 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005327 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005328 if (putenv(new)) {
5329 posix_error();
5330 return NULL;
5331 }
Fred Drake762e2061999-08-26 17:23:54 +00005332 /* Install the first arg and newstr in posix_putenv_garbage;
5333 * this will cause previous value to be collected. This has to
5334 * happen after the real putenv() call because the old value
5335 * was still accessible until then. */
5336 if (PyDict_SetItem(posix_putenv_garbage,
5337 PyTuple_GET_ITEM(args, 0), newstr)) {
5338 /* really not much we can do; just leak */
5339 PyErr_Clear();
5340 }
5341 else {
5342 Py_DECREF(newstr);
5343 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005344
5345#if defined(PYOS_OS2)
5346 }
5347#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005348 Py_INCREF(Py_None);
5349 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005350}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005351#endif /* putenv */
5352
Guido van Rossumc524d952001-10-19 01:31:59 +00005353#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005354PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005355"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005356Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005357
5358static PyObject *
5359posix_unsetenv(PyObject *self, PyObject *args)
5360{
5361 char *s1;
5362
5363 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5364 return NULL;
5365
5366 unsetenv(s1);
5367
5368 /* Remove the key from posix_putenv_garbage;
5369 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005370 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005371 * old value was still accessible until then.
5372 */
5373 if (PyDict_DelItem(posix_putenv_garbage,
5374 PyTuple_GET_ITEM(args, 0))) {
5375 /* really not much we can do; just leak */
5376 PyErr_Clear();
5377 }
5378
5379 Py_INCREF(Py_None);
5380 return Py_None;
5381}
5382#endif /* unsetenv */
5383
Guido van Rossumb6a47161997-09-15 22:54:34 +00005384#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005385PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005386"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005387Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005388
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005389static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005390posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005391{
5392 int code;
5393 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005394 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005395 return NULL;
5396 message = strerror(code);
5397 if (message == NULL) {
5398 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005399 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005400 return NULL;
5401 }
5402 return PyString_FromString(message);
5403}
5404#endif /* strerror */
5405
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005406
Guido van Rossumc9641791998-08-04 15:26:23 +00005407#ifdef HAVE_SYS_WAIT_H
5408
Fred Drake106c1a02002-04-23 15:58:02 +00005409#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005410PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005411"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005412Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005413
5414static PyObject *
5415posix_WCOREDUMP(PyObject *self, PyObject *args)
5416{
5417#ifdef UNION_WAIT
5418 union wait status;
5419#define status_i (status.w_status)
5420#else
5421 int status;
5422#define status_i status
5423#endif
5424 status_i = 0;
5425
5426 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
5427 {
5428 return NULL;
5429 }
5430
5431 return PyBool_FromLong(WCOREDUMP(status));
5432#undef status_i
5433}
5434#endif /* WCOREDUMP */
5435
5436#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005437PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005438"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005439Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005440job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005441
5442static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005443posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005444{
5445#ifdef UNION_WAIT
5446 union wait status;
5447#define status_i (status.w_status)
5448#else
5449 int status;
5450#define status_i status
5451#endif
5452 status_i = 0;
5453
5454 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
5455 {
5456 return NULL;
5457 }
5458
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005459 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005460#undef status_i
5461}
5462#endif /* WIFCONTINUED */
5463
Guido van Rossumc9641791998-08-04 15:26:23 +00005464#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005465PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005466"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005467Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005468
5469static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005470posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005471{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005472#ifdef UNION_WAIT
5473 union wait status;
5474#define status_i (status.w_status)
5475#else
5476 int status;
5477#define status_i status
5478#endif
5479 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005480
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005481 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005482 {
5483 return NULL;
5484 }
Tim Peters5aa91602002-01-30 05:46:57 +00005485
Fred Drake106c1a02002-04-23 15:58:02 +00005486 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005487#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005488}
5489#endif /* WIFSTOPPED */
5490
5491#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005492PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005493"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005494Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005495
5496static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005497posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005498{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005499#ifdef UNION_WAIT
5500 union wait status;
5501#define status_i (status.w_status)
5502#else
5503 int status;
5504#define status_i status
5505#endif
5506 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005507
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005508 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005509 {
5510 return NULL;
5511 }
Tim Peters5aa91602002-01-30 05:46:57 +00005512
Fred Drake106c1a02002-04-23 15:58:02 +00005513 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005514#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005515}
5516#endif /* WIFSIGNALED */
5517
5518#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005519PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005520"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005521Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005522system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005523
5524static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005525posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005526{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005527#ifdef UNION_WAIT
5528 union wait status;
5529#define status_i (status.w_status)
5530#else
5531 int status;
5532#define status_i status
5533#endif
5534 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005535
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005536 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005537 {
5538 return NULL;
5539 }
Tim Peters5aa91602002-01-30 05:46:57 +00005540
Fred Drake106c1a02002-04-23 15:58:02 +00005541 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005542#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005543}
5544#endif /* WIFEXITED */
5545
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005546#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005547PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005548"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005549Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005550
5551static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005552posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005553{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005554#ifdef UNION_WAIT
5555 union wait status;
5556#define status_i (status.w_status)
5557#else
5558 int status;
5559#define status_i status
5560#endif
5561 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005562
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005563 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005564 {
5565 return NULL;
5566 }
Tim Peters5aa91602002-01-30 05:46:57 +00005567
Guido van Rossumc9641791998-08-04 15:26:23 +00005568 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005569#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005570}
5571#endif /* WEXITSTATUS */
5572
5573#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005574PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005575"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005576Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005577value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005578
5579static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005580posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005581{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005582#ifdef UNION_WAIT
5583 union wait status;
5584#define status_i (status.w_status)
5585#else
5586 int status;
5587#define status_i status
5588#endif
5589 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005590
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005591 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005592 {
5593 return NULL;
5594 }
Tim Peters5aa91602002-01-30 05:46:57 +00005595
Guido van Rossumc9641791998-08-04 15:26:23 +00005596 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005597#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005598}
5599#endif /* WTERMSIG */
5600
5601#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005602PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005603"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005604Return the signal that stopped the process that provided\n\
5605the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005606
5607static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005608posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005609{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005610#ifdef UNION_WAIT
5611 union wait status;
5612#define status_i (status.w_status)
5613#else
5614 int status;
5615#define status_i status
5616#endif
5617 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005618
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005619 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005620 {
5621 return NULL;
5622 }
Tim Peters5aa91602002-01-30 05:46:57 +00005623
Guido van Rossumc9641791998-08-04 15:26:23 +00005624 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005625#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005626}
5627#endif /* WSTOPSIG */
5628
5629#endif /* HAVE_SYS_WAIT_H */
5630
5631
Guido van Rossum94f6f721999-01-06 18:42:14 +00005632#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005633#ifdef _SCO_DS
5634/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5635 needed definitions in sys/statvfs.h */
5636#define _SVID3
5637#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005638#include <sys/statvfs.h>
5639
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005640static PyObject*
5641_pystatvfs_fromstructstatvfs(struct statvfs st) {
5642 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5643 if (v == NULL)
5644 return NULL;
5645
5646#if !defined(HAVE_LARGEFILE_SUPPORT)
5647 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5648 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5649 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5650 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5651 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5652 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5653 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5654 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5655 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5656 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5657#else
5658 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5659 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005660 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005661 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005662 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005663 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
5664 PyStructSequence_SET_ITEM(v, 4,
5665 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005666 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005667 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005668 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005669 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005670 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005671 PyLong_FromLongLong((LONG_LONG) st.f_favail));
5672 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5673 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5674#endif
5675
5676 return v;
5677}
5678
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005679PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005680"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005681Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005682
5683static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005684posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005685{
5686 int fd, res;
5687 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005688
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005689 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005690 return NULL;
5691 Py_BEGIN_ALLOW_THREADS
5692 res = fstatvfs(fd, &st);
5693 Py_END_ALLOW_THREADS
5694 if (res != 0)
5695 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005696
5697 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005698}
5699#endif /* HAVE_FSTATVFS */
5700
5701
5702#if defined(HAVE_STATVFS)
5703#include <sys/statvfs.h>
5704
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005705PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005706"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005707Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005708
5709static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005710posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005711{
5712 char *path;
5713 int res;
5714 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005715 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005716 return NULL;
5717 Py_BEGIN_ALLOW_THREADS
5718 res = statvfs(path, &st);
5719 Py_END_ALLOW_THREADS
5720 if (res != 0)
5721 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005722
5723 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005724}
5725#endif /* HAVE_STATVFS */
5726
5727
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005728#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005729PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005730"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005731Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00005732The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005733or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005734
5735static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005736posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005737{
5738 PyObject *result = NULL;
5739 char *dir = NULL;
5740 char *pfx = NULL;
5741 char *name;
5742
5743 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5744 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005745
5746 if (PyErr_Warn(PyExc_RuntimeWarning,
5747 "tempnam is a potential security risk to your program") < 0)
5748 return NULL;
5749
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005750#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00005751 name = _tempnam(dir, pfx);
5752#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005753 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005754#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005755 if (name == NULL)
5756 return PyErr_NoMemory();
5757 result = PyString_FromString(name);
5758 free(name);
5759 return result;
5760}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005761#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005762
5763
5764#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005765PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005766"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005767Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005768
5769static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005770posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005771{
5772 FILE *fp;
5773
5774 if (!PyArg_ParseTuple(args, ":tmpfile"))
5775 return NULL;
5776 fp = tmpfile();
5777 if (fp == NULL)
5778 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00005779 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005780}
5781#endif
5782
5783
5784#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005785PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005786"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005787Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005788
5789static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005790posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005791{
5792 char buffer[L_tmpnam];
5793 char *name;
5794
5795 if (!PyArg_ParseTuple(args, ":tmpnam"))
5796 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005797
5798 if (PyErr_Warn(PyExc_RuntimeWarning,
5799 "tmpnam is a potential security risk to your program") < 0)
5800 return NULL;
5801
Greg Wardb48bc172000-03-01 21:51:56 +00005802#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005803 name = tmpnam_r(buffer);
5804#else
5805 name = tmpnam(buffer);
5806#endif
5807 if (name == NULL) {
5808 PyErr_SetObject(PyExc_OSError,
5809 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005810#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005811 "unexpected NULL from tmpnam_r"
5812#else
5813 "unexpected NULL from tmpnam"
5814#endif
5815 ));
5816 return NULL;
5817 }
5818 return PyString_FromString(buffer);
5819}
5820#endif
5821
5822
Fred Drakec9680921999-12-13 16:37:25 +00005823/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5824 * It maps strings representing configuration variable names to
5825 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005826 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005827 * rarely-used constants. There are three separate tables that use
5828 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005829 *
5830 * This code is always included, even if none of the interfaces that
5831 * need it are included. The #if hackery needed to avoid it would be
5832 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005833 */
5834struct constdef {
5835 char *name;
5836 long value;
5837};
5838
Fred Drake12c6e2d1999-12-14 21:25:03 +00005839static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005840conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5841 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005842{
5843 if (PyInt_Check(arg)) {
5844 *valuep = PyInt_AS_LONG(arg);
5845 return 1;
5846 }
5847 if (PyString_Check(arg)) {
5848 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005849 size_t lo = 0;
5850 size_t mid;
5851 size_t hi = tablesize;
5852 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005853 char *confname = PyString_AS_STRING(arg);
5854 while (lo < hi) {
5855 mid = (lo + hi) / 2;
5856 cmp = strcmp(confname, table[mid].name);
5857 if (cmp < 0)
5858 hi = mid;
5859 else if (cmp > 0)
5860 lo = mid + 1;
5861 else {
5862 *valuep = table[mid].value;
5863 return 1;
5864 }
5865 }
5866 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5867 }
5868 else
5869 PyErr_SetString(PyExc_TypeError,
5870 "configuration names must be strings or integers");
5871 return 0;
5872}
5873
5874
5875#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5876static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005877#ifdef _PC_ABI_AIO_XFER_MAX
5878 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5879#endif
5880#ifdef _PC_ABI_ASYNC_IO
5881 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5882#endif
Fred Drakec9680921999-12-13 16:37:25 +00005883#ifdef _PC_ASYNC_IO
5884 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5885#endif
5886#ifdef _PC_CHOWN_RESTRICTED
5887 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5888#endif
5889#ifdef _PC_FILESIZEBITS
5890 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5891#endif
5892#ifdef _PC_LAST
5893 {"PC_LAST", _PC_LAST},
5894#endif
5895#ifdef _PC_LINK_MAX
5896 {"PC_LINK_MAX", _PC_LINK_MAX},
5897#endif
5898#ifdef _PC_MAX_CANON
5899 {"PC_MAX_CANON", _PC_MAX_CANON},
5900#endif
5901#ifdef _PC_MAX_INPUT
5902 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5903#endif
5904#ifdef _PC_NAME_MAX
5905 {"PC_NAME_MAX", _PC_NAME_MAX},
5906#endif
5907#ifdef _PC_NO_TRUNC
5908 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5909#endif
5910#ifdef _PC_PATH_MAX
5911 {"PC_PATH_MAX", _PC_PATH_MAX},
5912#endif
5913#ifdef _PC_PIPE_BUF
5914 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5915#endif
5916#ifdef _PC_PRIO_IO
5917 {"PC_PRIO_IO", _PC_PRIO_IO},
5918#endif
5919#ifdef _PC_SOCK_MAXBUF
5920 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5921#endif
5922#ifdef _PC_SYNC_IO
5923 {"PC_SYNC_IO", _PC_SYNC_IO},
5924#endif
5925#ifdef _PC_VDISABLE
5926 {"PC_VDISABLE", _PC_VDISABLE},
5927#endif
5928};
5929
Fred Drakec9680921999-12-13 16:37:25 +00005930static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005931conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005932{
5933 return conv_confname(arg, valuep, posix_constants_pathconf,
5934 sizeof(posix_constants_pathconf)
5935 / sizeof(struct constdef));
5936}
5937#endif
5938
5939#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005940PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005941"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005942Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005943If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005944
5945static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005946posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005947{
5948 PyObject *result = NULL;
5949 int name, fd;
5950
Fred Drake12c6e2d1999-12-14 21:25:03 +00005951 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5952 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005953 long limit;
5954
5955 errno = 0;
5956 limit = fpathconf(fd, name);
5957 if (limit == -1 && errno != 0)
5958 posix_error();
5959 else
5960 result = PyInt_FromLong(limit);
5961 }
5962 return result;
5963}
5964#endif
5965
5966
5967#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005968PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005969"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005970Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005971If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005972
5973static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005974posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005975{
5976 PyObject *result = NULL;
5977 int name;
5978 char *path;
5979
5980 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5981 conv_path_confname, &name)) {
5982 long limit;
5983
5984 errno = 0;
5985 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005986 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005987 if (errno == EINVAL)
5988 /* could be a path or name problem */
5989 posix_error();
5990 else
5991 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005992 }
Fred Drakec9680921999-12-13 16:37:25 +00005993 else
5994 result = PyInt_FromLong(limit);
5995 }
5996 return result;
5997}
5998#endif
5999
6000#ifdef HAVE_CONFSTR
6001static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006002#ifdef _CS_ARCHITECTURE
6003 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6004#endif
6005#ifdef _CS_HOSTNAME
6006 {"CS_HOSTNAME", _CS_HOSTNAME},
6007#endif
6008#ifdef _CS_HW_PROVIDER
6009 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6010#endif
6011#ifdef _CS_HW_SERIAL
6012 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6013#endif
6014#ifdef _CS_INITTAB_NAME
6015 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6016#endif
Fred Drakec9680921999-12-13 16:37:25 +00006017#ifdef _CS_LFS64_CFLAGS
6018 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6019#endif
6020#ifdef _CS_LFS64_LDFLAGS
6021 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6022#endif
6023#ifdef _CS_LFS64_LIBS
6024 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6025#endif
6026#ifdef _CS_LFS64_LINTFLAGS
6027 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6028#endif
6029#ifdef _CS_LFS_CFLAGS
6030 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6031#endif
6032#ifdef _CS_LFS_LDFLAGS
6033 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6034#endif
6035#ifdef _CS_LFS_LIBS
6036 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6037#endif
6038#ifdef _CS_LFS_LINTFLAGS
6039 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6040#endif
Fred Draked86ed291999-12-15 15:34:33 +00006041#ifdef _CS_MACHINE
6042 {"CS_MACHINE", _CS_MACHINE},
6043#endif
Fred Drakec9680921999-12-13 16:37:25 +00006044#ifdef _CS_PATH
6045 {"CS_PATH", _CS_PATH},
6046#endif
Fred Draked86ed291999-12-15 15:34:33 +00006047#ifdef _CS_RELEASE
6048 {"CS_RELEASE", _CS_RELEASE},
6049#endif
6050#ifdef _CS_SRPC_DOMAIN
6051 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6052#endif
6053#ifdef _CS_SYSNAME
6054 {"CS_SYSNAME", _CS_SYSNAME},
6055#endif
6056#ifdef _CS_VERSION
6057 {"CS_VERSION", _CS_VERSION},
6058#endif
Fred Drakec9680921999-12-13 16:37:25 +00006059#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6060 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6061#endif
6062#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6063 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6064#endif
6065#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6066 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6067#endif
6068#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6069 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6070#endif
6071#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6072 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6073#endif
6074#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6075 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6076#endif
6077#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6078 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6079#endif
6080#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6081 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6082#endif
6083#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6084 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6085#endif
6086#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6087 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6088#endif
6089#ifdef _CS_XBS5_LP64_OFF64_LIBS
6090 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6091#endif
6092#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6093 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6094#endif
6095#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6096 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6097#endif
6098#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6099 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6100#endif
6101#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6102 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6103#endif
6104#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6105 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6106#endif
Fred Draked86ed291999-12-15 15:34:33 +00006107#ifdef _MIPS_CS_AVAIL_PROCESSORS
6108 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6109#endif
6110#ifdef _MIPS_CS_BASE
6111 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6112#endif
6113#ifdef _MIPS_CS_HOSTID
6114 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6115#endif
6116#ifdef _MIPS_CS_HW_NAME
6117 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6118#endif
6119#ifdef _MIPS_CS_NUM_PROCESSORS
6120 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6121#endif
6122#ifdef _MIPS_CS_OSREL_MAJ
6123 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6124#endif
6125#ifdef _MIPS_CS_OSREL_MIN
6126 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6127#endif
6128#ifdef _MIPS_CS_OSREL_PATCH
6129 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6130#endif
6131#ifdef _MIPS_CS_OS_NAME
6132 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6133#endif
6134#ifdef _MIPS_CS_OS_PROVIDER
6135 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6136#endif
6137#ifdef _MIPS_CS_PROCESSORS
6138 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6139#endif
6140#ifdef _MIPS_CS_SERIAL
6141 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6142#endif
6143#ifdef _MIPS_CS_VENDOR
6144 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6145#endif
Fred Drakec9680921999-12-13 16:37:25 +00006146};
6147
6148static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006149conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006150{
6151 return conv_confname(arg, valuep, posix_constants_confstr,
6152 sizeof(posix_constants_confstr)
6153 / sizeof(struct constdef));
6154}
6155
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006156PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006157"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006158Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006159
6160static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006161posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006162{
6163 PyObject *result = NULL;
6164 int name;
6165 char buffer[64];
6166
6167 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6168 int len = confstr(name, buffer, sizeof(buffer));
6169
Fred Drakec9680921999-12-13 16:37:25 +00006170 errno = 0;
6171 if (len == 0) {
6172 if (errno != 0)
6173 posix_error();
6174 else
6175 result = PyString_FromString("");
6176 }
6177 else {
6178 if (len >= sizeof(buffer)) {
6179 result = PyString_FromStringAndSize(NULL, len);
6180 if (result != NULL)
6181 confstr(name, PyString_AS_STRING(result), len+1);
6182 }
6183 else
6184 result = PyString_FromString(buffer);
6185 }
6186 }
6187 return result;
6188}
6189#endif
6190
6191
6192#ifdef HAVE_SYSCONF
6193static struct constdef posix_constants_sysconf[] = {
6194#ifdef _SC_2_CHAR_TERM
6195 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6196#endif
6197#ifdef _SC_2_C_BIND
6198 {"SC_2_C_BIND", _SC_2_C_BIND},
6199#endif
6200#ifdef _SC_2_C_DEV
6201 {"SC_2_C_DEV", _SC_2_C_DEV},
6202#endif
6203#ifdef _SC_2_C_VERSION
6204 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6205#endif
6206#ifdef _SC_2_FORT_DEV
6207 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6208#endif
6209#ifdef _SC_2_FORT_RUN
6210 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6211#endif
6212#ifdef _SC_2_LOCALEDEF
6213 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6214#endif
6215#ifdef _SC_2_SW_DEV
6216 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6217#endif
6218#ifdef _SC_2_UPE
6219 {"SC_2_UPE", _SC_2_UPE},
6220#endif
6221#ifdef _SC_2_VERSION
6222 {"SC_2_VERSION", _SC_2_VERSION},
6223#endif
Fred Draked86ed291999-12-15 15:34:33 +00006224#ifdef _SC_ABI_ASYNCHRONOUS_IO
6225 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6226#endif
6227#ifdef _SC_ACL
6228 {"SC_ACL", _SC_ACL},
6229#endif
Fred Drakec9680921999-12-13 16:37:25 +00006230#ifdef _SC_AIO_LISTIO_MAX
6231 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6232#endif
Fred Drakec9680921999-12-13 16:37:25 +00006233#ifdef _SC_AIO_MAX
6234 {"SC_AIO_MAX", _SC_AIO_MAX},
6235#endif
6236#ifdef _SC_AIO_PRIO_DELTA_MAX
6237 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6238#endif
6239#ifdef _SC_ARG_MAX
6240 {"SC_ARG_MAX", _SC_ARG_MAX},
6241#endif
6242#ifdef _SC_ASYNCHRONOUS_IO
6243 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6244#endif
6245#ifdef _SC_ATEXIT_MAX
6246 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6247#endif
Fred Draked86ed291999-12-15 15:34:33 +00006248#ifdef _SC_AUDIT
6249 {"SC_AUDIT", _SC_AUDIT},
6250#endif
Fred Drakec9680921999-12-13 16:37:25 +00006251#ifdef _SC_AVPHYS_PAGES
6252 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6253#endif
6254#ifdef _SC_BC_BASE_MAX
6255 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6256#endif
6257#ifdef _SC_BC_DIM_MAX
6258 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6259#endif
6260#ifdef _SC_BC_SCALE_MAX
6261 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6262#endif
6263#ifdef _SC_BC_STRING_MAX
6264 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6265#endif
Fred Draked86ed291999-12-15 15:34:33 +00006266#ifdef _SC_CAP
6267 {"SC_CAP", _SC_CAP},
6268#endif
Fred Drakec9680921999-12-13 16:37:25 +00006269#ifdef _SC_CHARCLASS_NAME_MAX
6270 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6271#endif
6272#ifdef _SC_CHAR_BIT
6273 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6274#endif
6275#ifdef _SC_CHAR_MAX
6276 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6277#endif
6278#ifdef _SC_CHAR_MIN
6279 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6280#endif
6281#ifdef _SC_CHILD_MAX
6282 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6283#endif
6284#ifdef _SC_CLK_TCK
6285 {"SC_CLK_TCK", _SC_CLK_TCK},
6286#endif
6287#ifdef _SC_COHER_BLKSZ
6288 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6289#endif
6290#ifdef _SC_COLL_WEIGHTS_MAX
6291 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6292#endif
6293#ifdef _SC_DCACHE_ASSOC
6294 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6295#endif
6296#ifdef _SC_DCACHE_BLKSZ
6297 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6298#endif
6299#ifdef _SC_DCACHE_LINESZ
6300 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6301#endif
6302#ifdef _SC_DCACHE_SZ
6303 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6304#endif
6305#ifdef _SC_DCACHE_TBLKSZ
6306 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6307#endif
6308#ifdef _SC_DELAYTIMER_MAX
6309 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6310#endif
6311#ifdef _SC_EQUIV_CLASS_MAX
6312 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6313#endif
6314#ifdef _SC_EXPR_NEST_MAX
6315 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6316#endif
6317#ifdef _SC_FSYNC
6318 {"SC_FSYNC", _SC_FSYNC},
6319#endif
6320#ifdef _SC_GETGR_R_SIZE_MAX
6321 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6322#endif
6323#ifdef _SC_GETPW_R_SIZE_MAX
6324 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6325#endif
6326#ifdef _SC_ICACHE_ASSOC
6327 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6328#endif
6329#ifdef _SC_ICACHE_BLKSZ
6330 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6331#endif
6332#ifdef _SC_ICACHE_LINESZ
6333 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6334#endif
6335#ifdef _SC_ICACHE_SZ
6336 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6337#endif
Fred Draked86ed291999-12-15 15:34:33 +00006338#ifdef _SC_INF
6339 {"SC_INF", _SC_INF},
6340#endif
Fred Drakec9680921999-12-13 16:37:25 +00006341#ifdef _SC_INT_MAX
6342 {"SC_INT_MAX", _SC_INT_MAX},
6343#endif
6344#ifdef _SC_INT_MIN
6345 {"SC_INT_MIN", _SC_INT_MIN},
6346#endif
6347#ifdef _SC_IOV_MAX
6348 {"SC_IOV_MAX", _SC_IOV_MAX},
6349#endif
Fred Draked86ed291999-12-15 15:34:33 +00006350#ifdef _SC_IP_SECOPTS
6351 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6352#endif
Fred Drakec9680921999-12-13 16:37:25 +00006353#ifdef _SC_JOB_CONTROL
6354 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6355#endif
Fred Draked86ed291999-12-15 15:34:33 +00006356#ifdef _SC_KERN_POINTERS
6357 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6358#endif
6359#ifdef _SC_KERN_SIM
6360 {"SC_KERN_SIM", _SC_KERN_SIM},
6361#endif
Fred Drakec9680921999-12-13 16:37:25 +00006362#ifdef _SC_LINE_MAX
6363 {"SC_LINE_MAX", _SC_LINE_MAX},
6364#endif
6365#ifdef _SC_LOGIN_NAME_MAX
6366 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6367#endif
6368#ifdef _SC_LOGNAME_MAX
6369 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6370#endif
6371#ifdef _SC_LONG_BIT
6372 {"SC_LONG_BIT", _SC_LONG_BIT},
6373#endif
Fred Draked86ed291999-12-15 15:34:33 +00006374#ifdef _SC_MAC
6375 {"SC_MAC", _SC_MAC},
6376#endif
Fred Drakec9680921999-12-13 16:37:25 +00006377#ifdef _SC_MAPPED_FILES
6378 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6379#endif
6380#ifdef _SC_MAXPID
6381 {"SC_MAXPID", _SC_MAXPID},
6382#endif
6383#ifdef _SC_MB_LEN_MAX
6384 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6385#endif
6386#ifdef _SC_MEMLOCK
6387 {"SC_MEMLOCK", _SC_MEMLOCK},
6388#endif
6389#ifdef _SC_MEMLOCK_RANGE
6390 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6391#endif
6392#ifdef _SC_MEMORY_PROTECTION
6393 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6394#endif
6395#ifdef _SC_MESSAGE_PASSING
6396 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6397#endif
Fred Draked86ed291999-12-15 15:34:33 +00006398#ifdef _SC_MMAP_FIXED_ALIGNMENT
6399 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6400#endif
Fred Drakec9680921999-12-13 16:37:25 +00006401#ifdef _SC_MQ_OPEN_MAX
6402 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6403#endif
6404#ifdef _SC_MQ_PRIO_MAX
6405 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6406#endif
Fred Draked86ed291999-12-15 15:34:33 +00006407#ifdef _SC_NACLS_MAX
6408 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6409#endif
Fred Drakec9680921999-12-13 16:37:25 +00006410#ifdef _SC_NGROUPS_MAX
6411 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6412#endif
6413#ifdef _SC_NL_ARGMAX
6414 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6415#endif
6416#ifdef _SC_NL_LANGMAX
6417 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6418#endif
6419#ifdef _SC_NL_MSGMAX
6420 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6421#endif
6422#ifdef _SC_NL_NMAX
6423 {"SC_NL_NMAX", _SC_NL_NMAX},
6424#endif
6425#ifdef _SC_NL_SETMAX
6426 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6427#endif
6428#ifdef _SC_NL_TEXTMAX
6429 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6430#endif
6431#ifdef _SC_NPROCESSORS_CONF
6432 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6433#endif
6434#ifdef _SC_NPROCESSORS_ONLN
6435 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6436#endif
Fred Draked86ed291999-12-15 15:34:33 +00006437#ifdef _SC_NPROC_CONF
6438 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6439#endif
6440#ifdef _SC_NPROC_ONLN
6441 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6442#endif
Fred Drakec9680921999-12-13 16:37:25 +00006443#ifdef _SC_NZERO
6444 {"SC_NZERO", _SC_NZERO},
6445#endif
6446#ifdef _SC_OPEN_MAX
6447 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6448#endif
6449#ifdef _SC_PAGESIZE
6450 {"SC_PAGESIZE", _SC_PAGESIZE},
6451#endif
6452#ifdef _SC_PAGE_SIZE
6453 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6454#endif
6455#ifdef _SC_PASS_MAX
6456 {"SC_PASS_MAX", _SC_PASS_MAX},
6457#endif
6458#ifdef _SC_PHYS_PAGES
6459 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6460#endif
6461#ifdef _SC_PII
6462 {"SC_PII", _SC_PII},
6463#endif
6464#ifdef _SC_PII_INTERNET
6465 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6466#endif
6467#ifdef _SC_PII_INTERNET_DGRAM
6468 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6469#endif
6470#ifdef _SC_PII_INTERNET_STREAM
6471 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6472#endif
6473#ifdef _SC_PII_OSI
6474 {"SC_PII_OSI", _SC_PII_OSI},
6475#endif
6476#ifdef _SC_PII_OSI_CLTS
6477 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6478#endif
6479#ifdef _SC_PII_OSI_COTS
6480 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6481#endif
6482#ifdef _SC_PII_OSI_M
6483 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6484#endif
6485#ifdef _SC_PII_SOCKET
6486 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6487#endif
6488#ifdef _SC_PII_XTI
6489 {"SC_PII_XTI", _SC_PII_XTI},
6490#endif
6491#ifdef _SC_POLL
6492 {"SC_POLL", _SC_POLL},
6493#endif
6494#ifdef _SC_PRIORITIZED_IO
6495 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6496#endif
6497#ifdef _SC_PRIORITY_SCHEDULING
6498 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6499#endif
6500#ifdef _SC_REALTIME_SIGNALS
6501 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6502#endif
6503#ifdef _SC_RE_DUP_MAX
6504 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6505#endif
6506#ifdef _SC_RTSIG_MAX
6507 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6508#endif
6509#ifdef _SC_SAVED_IDS
6510 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6511#endif
6512#ifdef _SC_SCHAR_MAX
6513 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6514#endif
6515#ifdef _SC_SCHAR_MIN
6516 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6517#endif
6518#ifdef _SC_SELECT
6519 {"SC_SELECT", _SC_SELECT},
6520#endif
6521#ifdef _SC_SEMAPHORES
6522 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6523#endif
6524#ifdef _SC_SEM_NSEMS_MAX
6525 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6526#endif
6527#ifdef _SC_SEM_VALUE_MAX
6528 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6529#endif
6530#ifdef _SC_SHARED_MEMORY_OBJECTS
6531 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6532#endif
6533#ifdef _SC_SHRT_MAX
6534 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6535#endif
6536#ifdef _SC_SHRT_MIN
6537 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6538#endif
6539#ifdef _SC_SIGQUEUE_MAX
6540 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6541#endif
6542#ifdef _SC_SIGRT_MAX
6543 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6544#endif
6545#ifdef _SC_SIGRT_MIN
6546 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6547#endif
Fred Draked86ed291999-12-15 15:34:33 +00006548#ifdef _SC_SOFTPOWER
6549 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6550#endif
Fred Drakec9680921999-12-13 16:37:25 +00006551#ifdef _SC_SPLIT_CACHE
6552 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6553#endif
6554#ifdef _SC_SSIZE_MAX
6555 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6556#endif
6557#ifdef _SC_STACK_PROT
6558 {"SC_STACK_PROT", _SC_STACK_PROT},
6559#endif
6560#ifdef _SC_STREAM_MAX
6561 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6562#endif
6563#ifdef _SC_SYNCHRONIZED_IO
6564 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6565#endif
6566#ifdef _SC_THREADS
6567 {"SC_THREADS", _SC_THREADS},
6568#endif
6569#ifdef _SC_THREAD_ATTR_STACKADDR
6570 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6571#endif
6572#ifdef _SC_THREAD_ATTR_STACKSIZE
6573 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6574#endif
6575#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6576 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6577#endif
6578#ifdef _SC_THREAD_KEYS_MAX
6579 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6580#endif
6581#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6582 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6583#endif
6584#ifdef _SC_THREAD_PRIO_INHERIT
6585 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6586#endif
6587#ifdef _SC_THREAD_PRIO_PROTECT
6588 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6589#endif
6590#ifdef _SC_THREAD_PROCESS_SHARED
6591 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6592#endif
6593#ifdef _SC_THREAD_SAFE_FUNCTIONS
6594 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6595#endif
6596#ifdef _SC_THREAD_STACK_MIN
6597 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6598#endif
6599#ifdef _SC_THREAD_THREADS_MAX
6600 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6601#endif
6602#ifdef _SC_TIMERS
6603 {"SC_TIMERS", _SC_TIMERS},
6604#endif
6605#ifdef _SC_TIMER_MAX
6606 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6607#endif
6608#ifdef _SC_TTY_NAME_MAX
6609 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6610#endif
6611#ifdef _SC_TZNAME_MAX
6612 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6613#endif
6614#ifdef _SC_T_IOV_MAX
6615 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6616#endif
6617#ifdef _SC_UCHAR_MAX
6618 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6619#endif
6620#ifdef _SC_UINT_MAX
6621 {"SC_UINT_MAX", _SC_UINT_MAX},
6622#endif
6623#ifdef _SC_UIO_MAXIOV
6624 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6625#endif
6626#ifdef _SC_ULONG_MAX
6627 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6628#endif
6629#ifdef _SC_USHRT_MAX
6630 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6631#endif
6632#ifdef _SC_VERSION
6633 {"SC_VERSION", _SC_VERSION},
6634#endif
6635#ifdef _SC_WORD_BIT
6636 {"SC_WORD_BIT", _SC_WORD_BIT},
6637#endif
6638#ifdef _SC_XBS5_ILP32_OFF32
6639 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6640#endif
6641#ifdef _SC_XBS5_ILP32_OFFBIG
6642 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6643#endif
6644#ifdef _SC_XBS5_LP64_OFF64
6645 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6646#endif
6647#ifdef _SC_XBS5_LPBIG_OFFBIG
6648 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6649#endif
6650#ifdef _SC_XOPEN_CRYPT
6651 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6652#endif
6653#ifdef _SC_XOPEN_ENH_I18N
6654 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6655#endif
6656#ifdef _SC_XOPEN_LEGACY
6657 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6658#endif
6659#ifdef _SC_XOPEN_REALTIME
6660 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6661#endif
6662#ifdef _SC_XOPEN_REALTIME_THREADS
6663 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6664#endif
6665#ifdef _SC_XOPEN_SHM
6666 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6667#endif
6668#ifdef _SC_XOPEN_UNIX
6669 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6670#endif
6671#ifdef _SC_XOPEN_VERSION
6672 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6673#endif
6674#ifdef _SC_XOPEN_XCU_VERSION
6675 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6676#endif
6677#ifdef _SC_XOPEN_XPG2
6678 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6679#endif
6680#ifdef _SC_XOPEN_XPG3
6681 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6682#endif
6683#ifdef _SC_XOPEN_XPG4
6684 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6685#endif
6686};
6687
6688static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006689conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006690{
6691 return conv_confname(arg, valuep, posix_constants_sysconf,
6692 sizeof(posix_constants_sysconf)
6693 / sizeof(struct constdef));
6694}
6695
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006696PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006697"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006698Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006699
6700static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006701posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006702{
6703 PyObject *result = NULL;
6704 int name;
6705
6706 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6707 int value;
6708
6709 errno = 0;
6710 value = sysconf(name);
6711 if (value == -1 && errno != 0)
6712 posix_error();
6713 else
6714 result = PyInt_FromLong(value);
6715 }
6716 return result;
6717}
6718#endif
6719
6720
Fred Drakebec628d1999-12-15 18:31:10 +00006721/* This code is used to ensure that the tables of configuration value names
6722 * are in sorted order as required by conv_confname(), and also to build the
6723 * the exported dictionaries that are used to publish information about the
6724 * names available on the host platform.
6725 *
6726 * Sorting the table at runtime ensures that the table is properly ordered
6727 * when used, even for platforms we're not able to test on. It also makes
6728 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006729 */
Fred Drakebec628d1999-12-15 18:31:10 +00006730
6731static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006732cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006733{
6734 const struct constdef *c1 =
6735 (const struct constdef *) v1;
6736 const struct constdef *c2 =
6737 (const struct constdef *) v2;
6738
6739 return strcmp(c1->name, c2->name);
6740}
6741
6742static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006743setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006744 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006745{
Fred Drakebec628d1999-12-15 18:31:10 +00006746 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006747 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006748
6749 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6750 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006751 if (d == NULL)
6752 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006753
Barry Warsaw3155db32000-04-13 15:20:40 +00006754 for (i=0; i < tablesize; ++i) {
6755 PyObject *o = PyInt_FromLong(table[i].value);
6756 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6757 Py_XDECREF(o);
6758 Py_DECREF(d);
6759 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006760 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006761 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006762 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006763 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006764}
6765
Fred Drakebec628d1999-12-15 18:31:10 +00006766/* Return -1 on failure, 0 on success. */
6767static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006768setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006769{
6770#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006771 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006772 sizeof(posix_constants_pathconf)
6773 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006774 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006775 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006776#endif
6777#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006778 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006779 sizeof(posix_constants_confstr)
6780 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006781 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006782 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006783#endif
6784#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006785 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006786 sizeof(posix_constants_sysconf)
6787 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006788 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006789 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006790#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006791 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006792}
Fred Draked86ed291999-12-15 15:34:33 +00006793
6794
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006795PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006796"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006797Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006798in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006799
6800static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006801posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006802{
6803 if (!PyArg_ParseTuple(args, ":abort"))
6804 return NULL;
6805 abort();
6806 /*NOTREACHED*/
6807 Py_FatalError("abort() called from Python code didn't abort!");
6808 return NULL;
6809}
Fred Drakebec628d1999-12-15 18:31:10 +00006810
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006811#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006812PyDoc_STRVAR(win32_startfile__doc__,
6813"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006814\n\
6815This acts like double-clicking the file in Explorer, or giving the file\n\
6816name as an argument to the DOS \"start\" command: the file is opened\n\
6817with whatever application (if any) its extension is associated.\n\
6818\n\
6819startfile returns as soon as the associated application is launched.\n\
6820There is no option to wait for the application to close, and no way\n\
6821to retrieve the application's exit status.\n\
6822\n\
6823The filepath is relative to the current directory. If you want to use\n\
6824an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006825the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006826
6827static PyObject *
6828win32_startfile(PyObject *self, PyObject *args)
6829{
6830 char *filepath;
6831 HINSTANCE rc;
6832 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6833 return NULL;
6834 Py_BEGIN_ALLOW_THREADS
6835 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6836 Py_END_ALLOW_THREADS
6837 if (rc <= (HINSTANCE)32)
6838 return win32_error("startfile", filepath);
6839 Py_INCREF(Py_None);
6840 return Py_None;
6841}
6842#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006843
6844static PyMethodDef posix_methods[] = {
6845 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6846#ifdef HAVE_TTYNAME
6847 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6848#endif
6849 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6850 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006851#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006852 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006853#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00006854#ifdef HAVE_LCHOWN
6855 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
6856#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006857#ifdef HAVE_CHROOT
6858 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6859#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006860#ifdef HAVE_CTERMID
6861 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
6862#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006863#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006864 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00006865#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006866 {"getcwdu", posix_getcwdu, METH_VARARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006867#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00006868#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006869#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006870 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006871#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006872 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6873 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6874 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006875#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006876 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006877#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006878#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006879 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006880#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006881 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6882 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6883 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00006884 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006885#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006886 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006887#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006888#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006889 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006890#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006891 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006892#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006893 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006894#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006895 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6896 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6897 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006898#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006899 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006900#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006901 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006902#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006903 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6904 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006905#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006906#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006907 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6908 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006909#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006910#ifdef HAVE_FORK1
6911 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
6912#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006913#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006914 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006915#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006916#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006917 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00006918#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006919#ifdef HAVE_FORKPTY
6920 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
6921#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006922#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006923 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006924#endif /* HAVE_GETEGID */
6925#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006926 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006927#endif /* HAVE_GETEUID */
6928#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006929 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006930#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006931#ifdef HAVE_GETGROUPS
6932 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
6933#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006934 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006935#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006936 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006937#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006938#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006939 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006940#endif /* HAVE_GETPPID */
6941#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006942 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006943#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006944#ifdef HAVE_GETLOGIN
6945 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
6946#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006947#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006948 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006949#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006950#ifdef HAVE_KILLPG
6951 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6952#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006953#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006954 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006955#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006956#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006957 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006958#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006959 {"popen2", win32_popen2, METH_VARARGS},
6960 {"popen3", win32_popen3, METH_VARARGS},
6961 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00006962 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006963#else
6964#if defined(PYOS_OS2) && defined(PYCC_GCC)
6965 {"popen2", os2emx_popen2, METH_VARARGS},
6966 {"popen3", os2emx_popen3, METH_VARARGS},
6967 {"popen4", os2emx_popen4, METH_VARARGS},
6968#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006969#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006970#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006971#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006972 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006973#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006974#ifdef HAVE_SETEUID
6975 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6976#endif /* HAVE_SETEUID */
6977#ifdef HAVE_SETEGID
6978 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6979#endif /* HAVE_SETEGID */
6980#ifdef HAVE_SETREUID
6981 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6982#endif /* HAVE_SETREUID */
6983#ifdef HAVE_SETREGID
6984 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6985#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006986#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006987 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006988#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006989#ifdef HAVE_SETGROUPS
6990 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
6991#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00006992#ifdef HAVE_GETPGID
6993 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
6994#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006995#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006996 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006997#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006998#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006999 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007000#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00007001#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007002 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007003#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007004#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007005 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007006#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007007#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007008 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007009#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007010#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007011 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007012#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007013#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007014 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007015#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007016 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7017 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7018 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7019 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7020 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7021 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7022 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7023 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7024 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007025 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007026#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007027 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007028#endif
7029#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007030 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007031#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007032#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007033 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7034#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007035#ifdef HAVE_DEVICE_MACROS
7036 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7037 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7038 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7039#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007040#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007041 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007042#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007043#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007044 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007045#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007046#ifdef HAVE_UNSETENV
7047 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7048#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007049#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007050 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007051#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007052#ifdef HAVE_FCHDIR
7053 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7054#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007055#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007056 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007057#endif
7058#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007059 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007060#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007061#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007062#ifdef WCOREDUMP
7063 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7064#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007065#ifdef WIFCONTINUED
7066 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7067#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007068#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007069 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007070#endif /* WIFSTOPPED */
7071#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007072 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007073#endif /* WIFSIGNALED */
7074#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007075 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007076#endif /* WIFEXITED */
7077#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007078 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007079#endif /* WEXITSTATUS */
7080#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007081 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007082#endif /* WTERMSIG */
7083#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007084 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007085#endif /* WSTOPSIG */
7086#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007087#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007088 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007089#endif
7090#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007091 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007092#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007093#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007094 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
7095#endif
7096#ifdef HAVE_TEMPNAM
7097 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7098#endif
7099#ifdef HAVE_TMPNAM
7100 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
7101#endif
Fred Drakec9680921999-12-13 16:37:25 +00007102#ifdef HAVE_CONFSTR
7103 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7104#endif
7105#ifdef HAVE_SYSCONF
7106 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7107#endif
7108#ifdef HAVE_FPATHCONF
7109 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7110#endif
7111#ifdef HAVE_PATHCONF
7112 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7113#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007114 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007115#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007116 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7117#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007118 {NULL, NULL} /* Sentinel */
7119};
7120
7121
Barry Warsaw4a342091996-12-19 23:50:02 +00007122static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007123ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007124{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007125 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007126}
7127
Guido van Rossumd48f2521997-12-05 22:19:34 +00007128#if defined(PYOS_OS2)
7129/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007130static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007131{
7132 APIRET rc;
7133 ULONG values[QSV_MAX+1];
7134 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007135 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007136
7137 Py_BEGIN_ALLOW_THREADS
7138 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
7139 Py_END_ALLOW_THREADS
7140
7141 if (rc != NO_ERROR) {
7142 os2_error(rc);
7143 return -1;
7144 }
7145
Fred Drake4d1e64b2002-04-15 19:40:07 +00007146 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7147 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7148 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7149 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7150 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7151 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7152 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007153
7154 switch (values[QSV_VERSION_MINOR]) {
7155 case 0: ver = "2.00"; break;
7156 case 10: ver = "2.10"; break;
7157 case 11: ver = "2.11"; break;
7158 case 30: ver = "3.00"; break;
7159 case 40: ver = "4.00"; break;
7160 case 50: ver = "5.00"; break;
7161 default:
Tim Peters885d4572001-11-28 20:27:42 +00007162 PyOS_snprintf(tmp, sizeof(tmp),
7163 "%d-%d", values[QSV_VERSION_MAJOR],
7164 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007165 ver = &tmp[0];
7166 }
7167
7168 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007169 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007170 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007171
7172 /* Add Indicator of Which Drive was Used to Boot the System */
7173 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7174 tmp[1] = ':';
7175 tmp[2] = '\0';
7176
Fred Drake4d1e64b2002-04-15 19:40:07 +00007177 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007178}
7179#endif
7180
Barry Warsaw4a342091996-12-19 23:50:02 +00007181static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007182all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007183{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007184#ifdef F_OK
7185 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007186#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007187#ifdef R_OK
7188 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007189#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007190#ifdef W_OK
7191 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007192#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007193#ifdef X_OK
7194 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007195#endif
Fred Drakec9680921999-12-13 16:37:25 +00007196#ifdef NGROUPS_MAX
7197 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7198#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007199#ifdef TMP_MAX
7200 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7201#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007202#ifdef WCONTINUED
7203 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7204#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007205#ifdef WNOHANG
7206 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007207#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007208#ifdef WUNTRACED
7209 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7210#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007211#ifdef O_RDONLY
7212 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7213#endif
7214#ifdef O_WRONLY
7215 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7216#endif
7217#ifdef O_RDWR
7218 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7219#endif
7220#ifdef O_NDELAY
7221 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7222#endif
7223#ifdef O_NONBLOCK
7224 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7225#endif
7226#ifdef O_APPEND
7227 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7228#endif
7229#ifdef O_DSYNC
7230 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7231#endif
7232#ifdef O_RSYNC
7233 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7234#endif
7235#ifdef O_SYNC
7236 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7237#endif
7238#ifdef O_NOCTTY
7239 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7240#endif
7241#ifdef O_CREAT
7242 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7243#endif
7244#ifdef O_EXCL
7245 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7246#endif
7247#ifdef O_TRUNC
7248 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7249#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007250#ifdef O_BINARY
7251 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7252#endif
7253#ifdef O_TEXT
7254 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7255#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007256#ifdef O_LARGEFILE
7257 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7258#endif
7259
Tim Peters5aa91602002-01-30 05:46:57 +00007260/* MS Windows */
7261#ifdef O_NOINHERIT
7262 /* Don't inherit in child processes. */
7263 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7264#endif
7265#ifdef _O_SHORT_LIVED
7266 /* Optimize for short life (keep in memory). */
7267 /* MS forgot to define this one with a non-underscore form too. */
7268 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7269#endif
7270#ifdef O_TEMPORARY
7271 /* Automatically delete when last handle is closed. */
7272 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7273#endif
7274#ifdef O_RANDOM
7275 /* Optimize for random access. */
7276 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7277#endif
7278#ifdef O_SEQUENTIAL
7279 /* Optimize for sequential access. */
7280 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7281#endif
7282
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007283/* GNU extensions. */
7284#ifdef O_DIRECT
7285 /* Direct disk access. */
7286 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7287#endif
7288#ifdef O_DIRECTORY
7289 /* Must be a directory. */
7290 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7291#endif
7292#ifdef O_NOFOLLOW
7293 /* Do not follow links. */
7294 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7295#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007296
Guido van Rossum246bc171999-02-01 23:54:31 +00007297#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007298#if defined(PYOS_OS2) && defined(PYCC_GCC)
7299 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7300 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7301 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7302 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7303 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7304 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7305 if (ins(d, "P_PM", (long)P_PM)) return -1;
7306 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7307 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7308 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7309 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7310 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7311 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7312 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7313 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7314 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7315 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7316 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7317 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7318 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7319#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007320 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7321 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7322 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7323 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7324 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007325#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007326#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007327
Guido van Rossumd48f2521997-12-05 22:19:34 +00007328#if defined(PYOS_OS2)
7329 if (insertvalues(d)) return -1;
7330#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007331 return 0;
7332}
7333
7334
Tim Peters5aa91602002-01-30 05:46:57 +00007335#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007336#define INITFUNC initnt
7337#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007338
7339#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007340#define INITFUNC initos2
7341#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007342
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007343#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007344#define INITFUNC initposix
7345#define MODNAME "posix"
7346#endif
7347
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007348PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007349INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007350{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007351 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007352
Fred Drake4d1e64b2002-04-15 19:40:07 +00007353 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007354 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007355 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00007356
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007357 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007358 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007359 Py_XINCREF(v);
7360 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007361 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007362 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007363
Fred Drake4d1e64b2002-04-15 19:40:07 +00007364 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007365 return;
7366
Fred Drake4d1e64b2002-04-15 19:40:07 +00007367 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007368 return;
7369
Fred Drake4d1e64b2002-04-15 19:40:07 +00007370 Py_INCREF(PyExc_OSError);
7371 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007372
Guido van Rossumb3d39562000-01-31 18:41:26 +00007373#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007374 if (posix_putenv_garbage == NULL)
7375 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007376#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007377
Guido van Rossum14648392001-12-08 18:02:58 +00007378 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007379 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7380 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7381 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007382 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007383 structseq_new = StatResultType.tp_new;
7384 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00007385 Py_INCREF((PyObject*) &StatResultType);
7386 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007387
Guido van Rossum14648392001-12-08 18:02:58 +00007388 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007389 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007390 Py_INCREF((PyObject*) &StatVFSResultType);
7391 PyModule_AddObject(m, "statvfs_result",
7392 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00007393}