blob: ef0a42a7e242f9c4c927460005b12408dd6fab84 [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
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004/* This file is also used for Windows NT and MS-Win. In that case the module
Guido van Rossumad0ee831995-03-01 10:34:45 +00005 actually calls itself 'nt', not 'posix', and a few functions are
6 either unimplemented or implemented differently. The source
Guido van Rossum8d665e61996-06-26 18:22:49 +00007 assumes that for Windows NT, the macro 'MS_WIN32' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000012
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000013static char posix__doc__ [] =
14"This module provides access to operating system functionality that is\n\
15standardized by the C Standard and the POSIX standard (a thinly\n\
16disguised Unix interface). Refer to the library manual and\n\
17corresponding Unix manual entries for more information on calls.";
18
Barry Warsaw53699e91996-12-10 23:23:01 +000019#include "Python.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000020
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000021#if defined(PYOS_OS2)
22#define INCL_DOS
23#define INCL_DOSERRORS
24#define INCL_DOSPROCESS
25#define INCL_NOPMAPI
26#include <os2.h>
27#endif
28
Guido van Rossumb6775db1994-08-01 11:34:53 +000029#include <sys/types.h>
30#include <sys/stat.h>
Guido van Rossum36bc6801995-06-14 22:54:23 +000031#ifdef HAVE_SYS_WAIT_H
32#include <sys/wait.h> /* For WNOHANG */
33#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000034
Guido van Rossuma376cc51996-12-05 23:43:35 +000035#ifdef HAVE_SIGNAL_H
36#include <signal.h>
37#endif
38
Guido van Rossumb6775db1994-08-01 11:34:53 +000039#ifdef HAVE_FCNTL_H
40#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000041#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000042
Guido van Rossuma4916fa1996-05-23 22:58:55 +000043/* Various compilers have only certain posix functions */
Guido van Rossum6d8841c1997-08-14 19:57:39 +000044/* XXX Gosh I wish these were all moved into config.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000045#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000046#include <process.h>
47#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000048#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000049#define HAVE_GETCWD 1
50#define HAVE_OPENDIR 1
51#define HAVE_SYSTEM 1
52#if defined(__OS2__)
53#define HAVE_EXECV 1
54#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000055#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000056#include <process.h>
57#else
58#ifdef __BORLANDC__ /* Borland compiler */
59#define HAVE_EXECV 1
60#define HAVE_GETCWD 1
61#define HAVE_GETEGID 1
62#define HAVE_GETEUID 1
63#define HAVE_GETGID 1
64#define HAVE_GETPPID 1
65#define HAVE_GETUID 1
66#define HAVE_KILL 1
67#define HAVE_OPENDIR 1
68#define HAVE_PIPE 1
69#define HAVE_POPEN 1
70#define HAVE_SYSTEM 1
71#define HAVE_WAIT 1
72#else
73#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000074#define HAVE_GETCWD 1
75#ifdef MS_WIN32
Guido van Rossuma1065681999-01-25 23:20:23 +000076#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000077#define HAVE_EXECV 1
78#define HAVE_PIPE 1
79#define HAVE_POPEN 1
80#define HAVE_SYSTEM 1
81#else /* 16-bit Windows */
Guido van Rossum8d665e61996-06-26 18:22:49 +000082#endif /* !MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000083#else /* all other compilers */
84/* Unix functions that the configure script doesn't check for */
85#define HAVE_EXECV 1
86#define HAVE_FORK 1
87#define HAVE_GETCWD 1
88#define HAVE_GETEGID 1
89#define HAVE_GETEUID 1
90#define HAVE_GETGID 1
91#define HAVE_GETPPID 1
92#define HAVE_GETUID 1
93#define HAVE_KILL 1
94#define HAVE_OPENDIR 1
95#define HAVE_PIPE 1
96#define HAVE_POPEN 1
97#define HAVE_SYSTEM 1
98#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +000099#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000100#endif /* _MSC_VER */
101#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000102#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000103#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000104
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000105#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000106
Guido van Rossumb6775db1994-08-01 11:34:53 +0000107#ifdef HAVE_UNISTD_H
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000108#include <unistd.h>
Guido van Rossum36bc6801995-06-14 22:54:23 +0000109#endif
110
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000111#if defined(sun) && !defined(__SVR4)
112/* SunOS 4.1.4 doesn't have prototypes for these: */
113extern int rename(const char *, const char *);
114extern int pclose(FILE *);
115extern int fclose(FILE *);
116#endif
117
Guido van Rossum36bc6801995-06-14 22:54:23 +0000118#ifdef NeXT
119/* NeXT's <unistd.h> and <utime.h> aren't worth much */
120#undef HAVE_UNISTD_H
121#undef HAVE_UTIME_H
Guido van Rossumb9f866c1997-05-22 15:12:39 +0000122#define HAVE_WAITPID
Guido van Rossum36bc6801995-06-14 22:54:23 +0000123/* #undef HAVE_GETCWD */
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000124#define UNION_WAIT /* This should really be checked for by autoconf */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000125#endif
126
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000127#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000128#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000129extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000130#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000131#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000132extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000133#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000134extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000135#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000136#endif
137#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000138extern int chdir(char *);
139extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000140#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000141extern int chdir(const char *);
142extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000143#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000144extern int chmod(const char *, mode_t);
145extern int chown(const char *, uid_t, gid_t);
146extern char *getcwd(char *, int);
147extern char *strerror(int);
148extern int link(const char *, const char *);
149extern int rename(const char *, const char *);
150extern int stat(const char *, struct stat *);
151extern int unlink(const char *);
152extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000153#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000154extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000155#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000156#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000157extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000158#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000159#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000160
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000161#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000162
Guido van Rossumb6775db1994-08-01 11:34:53 +0000163#ifdef HAVE_UTIME_H
164#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000165#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000166
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000167#ifdef HAVE_SYS_UTIME_H
168#include <sys/utime.h>
169#define HAVE_UTIME_H /* pretend we do for the rest of this file */
170#endif /* HAVE_SYS_UTIME_H */
171
Guido van Rossumb6775db1994-08-01 11:34:53 +0000172#ifdef HAVE_SYS_TIMES_H
173#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000174#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000175
176#ifdef HAVE_SYS_PARAM_H
177#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000178#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000179
180#ifdef HAVE_SYS_UTSNAME_H
181#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000182#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000183
184#ifndef MAXPATHLEN
185#define MAXPATHLEN 1024
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000186#endif /* MAXPATHLEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000187
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000188#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000189#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000190#define NAMLEN(dirent) strlen((dirent)->d_name)
191#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000192#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000193#include <direct.h>
194#define NAMLEN(dirent) strlen((dirent)->d_name)
195#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000196#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000197#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000198#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000199#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000200#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000201#endif
202#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000203#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000204#endif
205#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000206#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000207#endif
208#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000209
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000210#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#include <direct.h>
212#include <io.h>
213#include <process.h>
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000214#define WINDOWS_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000215#include <windows.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000216#ifdef MS_WIN32
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000217#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000218#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000219#else /* 16-bit Windows */
220#include <dos.h>
221#include <ctype.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000222#endif /* MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000223#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224
Guido van Rossumd48f2521997-12-05 22:19:34 +0000225#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000227#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000228
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000229#ifdef UNION_WAIT
230/* Emulate some macros on systems that have a union instead of macros */
231
232#ifndef WIFEXITED
233#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
234#endif
235
236#ifndef WEXITSTATUS
237#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
238#endif
239
240#ifndef WTERMSIG
241#define WTERMSIG(u_wait) ((u_wait).w_termsig)
242#endif
243
244#endif /* UNION_WAIT */
245
Greg Wardb48bc172000-03-01 21:51:56 +0000246/* Don't use the "_r" form if we don't need it (also, won't have a
247 prototype for it, at least on Solaris -- maybe others as well?). */
248#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
249#define USE_CTERMID_R
250#endif
251
252#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
253#define USE_TMPNAM_R
254#endif
255
Fred Drake699f3522000-06-29 21:12:41 +0000256/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000257#undef STAT
Fred Drake699f3522000-06-29 21:12:41 +0000258#ifdef MS_WIN64
259# define STAT _stati64
260# define FSTAT _fstati64
261# define STRUCT_STAT struct _stati64
262#else
263# define STAT stat
264# define FSTAT fstat
265# define STRUCT_STAT struct stat
266#endif
267
268
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000269/* Return a dictionary corresponding to the POSIX environment table */
270
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000271#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000272extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000273#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000274
Barry Warsaw53699e91996-12-10 23:23:01 +0000275static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000276convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000277{
Barry Warsaw53699e91996-12-10 23:23:01 +0000278 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000279 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000280 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000281 if (d == NULL)
282 return NULL;
283 if (environ == NULL)
284 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000285 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000286 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000287 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000288 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000289 char *p = strchr(*e, '=');
290 if (p == NULL)
291 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000292 k = PyString_FromStringAndSize(*e, (int)(p-*e));
293 if (k == NULL) {
294 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000295 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000296 }
297 v = PyString_FromString(p+1);
298 if (v == NULL) {
299 PyErr_Clear();
300 Py_DECREF(k);
301 continue;
302 }
303 if (PyDict_GetItem(d, k) == NULL) {
304 if (PyDict_SetItem(d, k, v) != 0)
305 PyErr_Clear();
306 }
307 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000308 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000309 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000310#if defined(PYOS_OS2)
311 {
312 APIRET rc;
313 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
314
315 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000316 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000317 PyObject *v = PyString_FromString(buffer);
318 PyDict_SetItemString(d, "BEGINLIBPATH", v);
319 Py_DECREF(v);
320 }
321 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
322 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
323 PyObject *v = PyString_FromString(buffer);
324 PyDict_SetItemString(d, "ENDLIBPATH", v);
325 Py_DECREF(v);
326 }
327 }
328#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000329 return d;
330}
331
332
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000333/* Set a POSIX-specific error from errno, and return NULL */
334
Barry Warsawd58d7641998-07-23 16:14:40 +0000335static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000336posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000337{
Barry Warsawca74da41999-02-09 19:31:45 +0000338 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000339}
Barry Warsawd58d7641998-07-23 16:14:40 +0000340static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000341posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000342{
Barry Warsawca74da41999-02-09 19:31:45 +0000343 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000344}
345
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000346#ifdef MS_WIN32
347static PyObject *
348win32_error(char* function, char* filename)
349{
Mark Hammond33a6da92000-08-15 00:46:38 +0000350 /* XXX We should pass the function name along in the future.
351 (_winreg.c also wants to pass the function name.)
352 This would however require an additional param to the
353 Windows error object, which is non-trivial.
354 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000355 errno = GetLastError();
356 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000357 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000358 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000359 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000360}
361#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000362
Guido van Rossumd48f2521997-12-05 22:19:34 +0000363#if defined(PYOS_OS2)
364/**********************************************************************
365 * Helper Function to Trim and Format OS/2 Messages
366 **********************************************************************/
367 static void
368os2_formatmsg(char *msgbuf, int msglen, char *reason)
369{
370 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
371
372 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
373 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
374
375 while (lastc > msgbuf && isspace(*lastc))
376 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
377 }
378
379 /* Add Optional Reason Text */
380 if (reason) {
381 strcat(msgbuf, " : ");
382 strcat(msgbuf, reason);
383 }
384}
385
386/**********************************************************************
387 * Decode an OS/2 Operating System Error Code
388 *
389 * A convenience function to lookup an OS/2 error code and return a
390 * text message we can use to raise a Python exception.
391 *
392 * Notes:
393 * The messages for errors returned from the OS/2 kernel reside in
394 * the file OSO001.MSG in the \OS2 directory hierarchy.
395 *
396 **********************************************************************/
397 static char *
398os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
399{
400 APIRET rc;
401 ULONG msglen;
402
403 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
404 Py_BEGIN_ALLOW_THREADS
405 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
406 errorcode, "oso001.msg", &msglen);
407 Py_END_ALLOW_THREADS
408
409 if (rc == NO_ERROR)
410 os2_formatmsg(msgbuf, msglen, reason);
411 else
412 sprintf(msgbuf, "unknown OS error #%d", errorcode);
413
414 return msgbuf;
415}
416
417/* Set an OS/2-specific error and return NULL. OS/2 kernel
418 errors are not in a global variable e.g. 'errno' nor are
419 they congruent with posix error numbers. */
420
421static PyObject * os2_error(int code)
422{
423 char text[1024];
424 PyObject *v;
425
426 os2_strerror(text, sizeof(text), code, "");
427
428 v = Py_BuildValue("(is)", code, text);
429 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000430 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000431 Py_DECREF(v);
432 }
433 return NULL; /* Signal to Python that an Exception is Pending */
434}
435
436#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000437
438/* POSIX generic methods */
439
Barry Warsaw53699e91996-12-10 23:23:01 +0000440static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000441posix_int(PyObject *args, char *format, int (*func)(int))
Guido van Rossum21142a01999-01-08 21:05:37 +0000442{
443 int fd;
444 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000445 if (!PyArg_ParseTuple(args, format, &fd))
Guido van Rossum21142a01999-01-08 21:05:37 +0000446 return NULL;
447 Py_BEGIN_ALLOW_THREADS
448 res = (*func)(fd);
449 Py_END_ALLOW_THREADS
450 if (res < 0)
451 return posix_error();
452 Py_INCREF(Py_None);
453 return Py_None;
454}
455
456
457static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000458posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000459{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000460 char *path1;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000461 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000462 if (!PyArg_ParseTuple(args, format, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000463 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000464 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000465 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000466 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000467 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000468 return posix_error_with_filename(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000469 Py_INCREF(Py_None);
470 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000471}
472
Barry Warsaw53699e91996-12-10 23:23:01 +0000473static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000474posix_2str(PyObject *args, char *format,
475 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000476{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000477 char *path1, *path2;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000478 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000479 if (!PyArg_ParseTuple(args, format, &path1, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000480 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000481 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000482 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000483 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000484 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000485 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000486 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000487 Py_INCREF(Py_None);
488 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000489}
490
Fred Drake699f3522000-06-29 21:12:41 +0000491/* pack a system stat C structure into the Python stat tuple
492 (used by posix_stat() and posix_fstat()) */
493static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000494_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000495{
496 PyObject *v = PyTuple_New(10);
497 if (v == NULL)
498 return NULL;
499
500 PyTuple_SetItem(v, 0, PyInt_FromLong((long)st.st_mode));
501#ifdef HAVE_LARGEFILE_SUPPORT
502 PyTuple_SetItem(v, 1, PyLong_FromLongLong((LONG_LONG)st.st_ino));
503#else
504 PyTuple_SetItem(v, 1, PyInt_FromLong((long)st.st_ino));
505#endif
506#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
507 PyTuple_SetItem(v, 2, PyLong_FromLongLong((LONG_LONG)st.st_dev));
508#else
509 PyTuple_SetItem(v, 2, PyInt_FromLong((long)st.st_dev));
510#endif
511 PyTuple_SetItem(v, 3, PyInt_FromLong((long)st.st_nlink));
512 PyTuple_SetItem(v, 4, PyInt_FromLong((long)st.st_uid));
513 PyTuple_SetItem(v, 5, PyInt_FromLong((long)st.st_gid));
514#ifdef HAVE_LARGEFILE_SUPPORT
515 PyTuple_SetItem(v, 6, PyLong_FromLongLong((LONG_LONG)st.st_size));
516#else
517 PyTuple_SetItem(v, 6, PyInt_FromLong(st.st_size));
518#endif
519#if SIZEOF_TIME_T > SIZEOF_LONG
520 PyTuple_SetItem(v, 7, PyLong_FromLongLong((LONG_LONG)st.st_atime));
521 PyTuple_SetItem(v, 8, PyLong_FromLongLong((LONG_LONG)st.st_mtime));
522 PyTuple_SetItem(v, 9, PyLong_FromLongLong((LONG_LONG)st.st_ctime));
523#else
524 PyTuple_SetItem(v, 7, PyInt_FromLong((long)st.st_atime));
525 PyTuple_SetItem(v, 8, PyInt_FromLong((long)st.st_mtime));
526 PyTuple_SetItem(v, 9, PyInt_FromLong((long)st.st_ctime));
527#endif
528
529 if (PyErr_Occurred()) {
530 Py_DECREF(v);
531 return NULL;
532 }
533
534 return v;
535}
536
537
Barry Warsaw53699e91996-12-10 23:23:01 +0000538static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000539posix_do_stat(PyObject *self, PyObject *args, char *format,
540 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000541{
Fred Drake699f3522000-06-29 21:12:41 +0000542 STRUCT_STAT st;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000543 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000544 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000545
546#ifdef MS_WIN32
547 int pathlen;
548 char pathcopy[MAX_PATH];
549#endif /* MS_WIN32 */
550
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000551 if (!PyArg_ParseTuple(args, format, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000552 return NULL;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000553
554#ifdef MS_WIN32
555 pathlen = strlen(path);
556 /* the library call can blow up if the file name is too long! */
557 if (pathlen > MAX_PATH) {
558 errno = ENAMETOOLONG;
559 return posix_error();
560 }
561
562 if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) {
Guido van Rossum19dde102000-05-03 02:44:55 +0000563 /* exception for specific or current drive root */
564 if (!((pathlen == 1) ||
565 ((pathlen == 3) &&
Guido van Rossumace88ae2000-04-21 18:54:45 +0000566 (path[1] == ':') &&
Guido van Rossum19dde102000-05-03 02:44:55 +0000567 (path[2] == '\\' || path[2] == '/'))))
Guido van Rossumace88ae2000-04-21 18:54:45 +0000568 {
569 strncpy(pathcopy, path, pathlen);
570 pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */
571 path = pathcopy;
572 }
573 }
574#endif /* MS_WIN32 */
575
Barry Warsaw53699e91996-12-10 23:23:01 +0000576 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000577 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000578 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000579 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000580 return posix_error_with_filename(path);
Fred Drake699f3522000-06-29 21:12:41 +0000581
582 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000583}
584
585
586/* POSIX methods */
587
Guido van Rossum94f6f721999-01-06 18:42:14 +0000588static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000589"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000590Test for access to a file.";
591
592static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000593posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000594{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000595 char *path;
596 int mode;
597 int res;
598
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000599 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000600 return NULL;
601 Py_BEGIN_ALLOW_THREADS
602 res = access(path, mode);
603 Py_END_ALLOW_THREADS
604 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000605}
606
Guido van Rossumd371ff11999-01-25 16:12:23 +0000607#ifndef F_OK
608#define F_OK 0
609#endif
610#ifndef R_OK
611#define R_OK 4
612#endif
613#ifndef W_OK
614#define W_OK 2
615#endif
616#ifndef X_OK
617#define X_OK 1
618#endif
619
620#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000621static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000622"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000623Return the name of the terminal device connected to 'fd'.";
624
625static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000626posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000627{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000628 int id;
629 char *ret;
630
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000631 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000632 return NULL;
633
Guido van Rossum94f6f721999-01-06 18:42:14 +0000634 ret = ttyname(id);
635 if (ret == NULL)
636 return(posix_error());
637 return(PyString_FromString(ret));
638}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000639#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000640
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000641#ifdef HAVE_CTERMID
642static char posix_ctermid__doc__[] =
643"ctermid() -> String\n\
644Return the name of the controlling terminal for this process.";
645
646static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000647posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000648{
649 char *ret;
650 char buffer[L_ctermid];
651
652 if (!PyArg_ParseTuple(args, ":ctermid"))
653 return NULL;
654
Greg Wardb48bc172000-03-01 21:51:56 +0000655#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000656 ret = ctermid_r(buffer);
657#else
658 ret = ctermid(buffer);
659#endif
660 if (ret == NULL)
661 return(posix_error());
662 return(PyString_FromString(buffer));
663}
664#endif
665
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000666static char posix_chdir__doc__[] =
667"chdir(path) -> None\n\
668Change the current working directory to the specified path.";
669
Barry Warsaw53699e91996-12-10 23:23:01 +0000670static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000671posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000672{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000673 return posix_1str(args, "s:chdir", chdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000674}
675
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000676
677static char posix_chmod__doc__[] =
678"chmod(path, mode) -> None\n\
679Change the access permissions of a file.";
680
Barry Warsaw53699e91996-12-10 23:23:01 +0000681static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000682posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000683{
Guido van Rossumffd15f52000-03-31 00:47:28 +0000684 char *path;
685 int i;
686 int res;
Guido van Rossum49679b42000-03-31 00:48:21 +0000687 if (!PyArg_ParseTuple(args, "si", &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000688 return NULL;
689 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000690 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000691 Py_END_ALLOW_THREADS
692 if (res < 0)
693 return posix_error_with_filename(path);
694 Py_INCREF(Py_None);
695 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000696}
697
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000698
Guido van Rossum21142a01999-01-08 21:05:37 +0000699#ifdef HAVE_FSYNC
700static char posix_fsync__doc__[] =
701"fsync(fildes) -> None\n\
702force write of file with filedescriptor to disk.";
703
704static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000705posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000706{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000707 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000708}
709#endif /* HAVE_FSYNC */
710
711#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000712
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000713#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000714extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
715#endif
716
Guido van Rossum21142a01999-01-08 21:05:37 +0000717static char posix_fdatasync__doc__[] =
718"fdatasync(fildes) -> None\n\
719force write of file with filedescriptor to disk.\n\
720 does not force update of metadata.";
721
722static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000723posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000724{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000725 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000726}
727#endif /* HAVE_FDATASYNC */
728
729
Fredrik Lundh10723342000-07-10 16:38:09 +0000730#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000731static char posix_chown__doc__[] =
732"chown(path, uid, gid) -> None\n\
733Change the owner and group id of path to the numeric uid and gid.";
734
Barry Warsaw53699e91996-12-10 23:23:01 +0000735static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000736posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000737{
Fredrik Lundh44328e62000-07-10 15:59:30 +0000738 char *path;
739 int uid, gid;
740 int res;
741 if (!PyArg_ParseTuple(args, "sii:chown", &path, &uid, &gid))
742 return NULL;
743 Py_BEGIN_ALLOW_THREADS
744 res = chown(path, (uid_t) uid, (gid_t) gid);
745 Py_END_ALLOW_THREADS
746 if (res < 0)
747 return posix_error_with_filename(path);
748 Py_INCREF(Py_None);
749 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000750}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000751#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000752
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000753
Guido van Rossum36bc6801995-06-14 22:54:23 +0000754#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000755static char posix_getcwd__doc__[] =
756"getcwd() -> path\n\
757Return a string representing the current working directory.";
758
Barry Warsaw53699e91996-12-10 23:23:01 +0000759static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000760posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000761{
762 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000763 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000764 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000765 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000766 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000767 res = getcwd(buf, sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +0000768 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000769 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000770 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000771 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000772}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000773#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000774
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000775
Guido van Rossumb6775db1994-08-01 11:34:53 +0000776#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000777static char posix_link__doc__[] =
778"link(src, dst) -> None\n\
779Create a hard link to a file.";
780
Barry Warsaw53699e91996-12-10 23:23:01 +0000781static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000782posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000783{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000784 return posix_2str(args, "ss:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000785}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000786#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000787
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000788
789static char posix_listdir__doc__[] =
790"listdir(path) -> list_of_strings\n\
791Return a list containing the names of the entries in the directory.\n\
792\n\
793 path: path of directory to list\n\
794\n\
795The list is in arbitrary order. It does not include the special\n\
796entries '.' and '..' even if they are present in the directory.";
797
Barry Warsaw53699e91996-12-10 23:23:01 +0000798static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000799posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000800{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000801 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000802 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000803#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000804
Guido van Rossumb6775db1994-08-01 11:34:53 +0000805 char *name;
806 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000807 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000808 HANDLE hFindFile;
809 WIN32_FIND_DATA FileData;
810 char namebuf[MAX_PATH+5];
Tim Peters0bb44a42000-09-15 07:44:49 +0000811 char ch;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000812
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000813 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000814 return NULL;
815 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000816 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000817 return NULL;
818 }
819 strcpy(namebuf, name);
Tim Peters0bb44a42000-09-15 07:44:49 +0000820 ch = namebuf[len-1];
821 if (ch != '/' && ch != '\\' && ch != ':')
Guido van Rossumb6775db1994-08-01 11:34:53 +0000822 namebuf[len++] = '/';
823 strcpy(namebuf + len, "*.*");
824
Barry Warsaw53699e91996-12-10 23:23:01 +0000825 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000826 return NULL;
827
828 hFindFile = FindFirstFile(namebuf, &FileData);
829 if (hFindFile == INVALID_HANDLE_VALUE) {
830 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000831 if (errno == ERROR_FILE_NOT_FOUND)
832 return PyList_New(0);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000833 return win32_error("FindFirstFile", name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000834 }
835 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000836 if (FileData.cFileName[0] == '.' &&
837 (FileData.cFileName[1] == '\0' ||
838 FileData.cFileName[1] == '.' &&
839 FileData.cFileName[2] == '\0'))
840 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +0000841 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000842 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000843 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000844 d = NULL;
845 break;
846 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000847 if (PyList_Append(d, v) != 0) {
848 Py_DECREF(v);
849 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000850 d = NULL;
851 break;
852 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000853 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000854 } while (FindNextFile(hFindFile, &FileData) == TRUE);
855
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000856 if (FindClose(hFindFile) == FALSE)
857 return win32_error("FindClose", name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000858
859 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000860
Tim Peters0bb44a42000-09-15 07:44:49 +0000861#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000862
863#ifndef MAX_PATH
864#define MAX_PATH 250
865#endif
866 char *name, *pt;
867 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000868 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000869 char namebuf[MAX_PATH+5];
870 struct _find_t ep;
871
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000872 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000873 return NULL;
874 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000875 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000876 return NULL;
877 }
878 strcpy(namebuf, name);
879 for (pt = namebuf; *pt; pt++)
880 if (*pt == '/')
881 *pt = '\\';
882 if (namebuf[len-1] != '\\')
883 namebuf[len++] = '\\';
884 strcpy(namebuf + len, "*.*");
885
Barry Warsaw53699e91996-12-10 23:23:01 +0000886 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000887 return NULL;
888
889 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +0000890 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
891 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000892 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000893 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000894 }
895 do {
896 if (ep.name[0] == '.' &&
897 (ep.name[1] == '\0' ||
898 ep.name[1] == '.' &&
899 ep.name[2] == '\0'))
900 continue;
901 strcpy(namebuf, ep.name);
902 for (pt = namebuf; *pt; pt++)
903 if (isupper(*pt))
904 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +0000905 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000906 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000907 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000908 d = NULL;
909 break;
910 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000911 if (PyList_Append(d, v) != 0) {
912 Py_DECREF(v);
913 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000914 d = NULL;
915 break;
916 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000917 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000918 } while (_dos_findnext(&ep) == 0);
919
920 return d;
921
Tim Peters0bb44a42000-09-15 07:44:49 +0000922#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000923
924#ifndef MAX_PATH
925#define MAX_PATH CCHMAXPATH
926#endif
927 char *name, *pt;
928 int len;
929 PyObject *d, *v;
930 char namebuf[MAX_PATH+5];
931 HDIR hdir = 1;
932 ULONG srchcnt = 1;
933 FILEFINDBUF3 ep;
934 APIRET rc;
935
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000936 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000937 return NULL;
938 if (len >= MAX_PATH) {
939 PyErr_SetString(PyExc_ValueError, "path too long");
940 return NULL;
941 }
942 strcpy(namebuf, name);
943 for (pt = namebuf; *pt; pt++)
944 if (*pt == '/')
945 *pt = '\\';
946 if (namebuf[len-1] != '\\')
947 namebuf[len++] = '\\';
948 strcpy(namebuf + len, "*.*");
949
950 if ((d = PyList_New(0)) == NULL)
951 return NULL;
952
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000953 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
954 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000955 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000956 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
957 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
958 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000959
960 if (rc != NO_ERROR) {
961 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000962 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000963 }
964
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000965 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000966 do {
967 if (ep.achName[0] == '.'
968 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000969 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000970
971 strcpy(namebuf, ep.achName);
972
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000973 /* Leave Case of Name Alone -- In Native Form */
974 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000975
976 v = PyString_FromString(namebuf);
977 if (v == NULL) {
978 Py_DECREF(d);
979 d = NULL;
980 break;
981 }
982 if (PyList_Append(d, v) != 0) {
983 Py_DECREF(v);
984 Py_DECREF(d);
985 d = NULL;
986 break;
987 }
988 Py_DECREF(v);
989 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
990 }
991
992 return d;
993#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000994
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000995 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +0000996 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000997 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000998 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000999 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001000 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001001 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001002 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001003 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001004 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001005 closedir(dirp);
1006 return NULL;
1007 }
1008 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001009 if (ep->d_name[0] == '.' &&
1010 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001011 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001012 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001013 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001014 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001015 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001016 d = NULL;
1017 break;
1018 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001019 if (PyList_Append(d, v) != 0) {
1020 Py_DECREF(v);
1021 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001022 d = NULL;
1023 break;
1024 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001025 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001026 }
1027 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001028
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001029 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001030
Tim Peters0bb44a42000-09-15 07:44:49 +00001031#endif /* which OS */
1032} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001033
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001034static char posix_mkdir__doc__[] =
1035"mkdir(path [, mode=0777]) -> None\n\
1036Create a directory.";
1037
Barry Warsaw53699e91996-12-10 23:23:01 +00001038static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001039posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001040{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001041 int res;
1042 char *path;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001043 int mode = 0777;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001044 if (!PyArg_ParseTuple(args, "s|i:mkdir", &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001045 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001046 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001047#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001048 res = mkdir(path);
1049#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001050 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001051#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001052 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001053 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001054 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001055 Py_INCREF(Py_None);
1056 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001057}
1058
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001059
Guido van Rossumb6775db1994-08-01 11:34:53 +00001060#ifdef HAVE_NICE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001061static char posix_nice__doc__[] =
1062"nice(inc) -> new_priority\n\
1063Decrease the priority of process and return new priority.";
1064
Barry Warsaw53699e91996-12-10 23:23:01 +00001065static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001066posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001067{
1068 int increment, value;
1069
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001070 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001071 return NULL;
1072 value = nice(increment);
1073 if (value == -1)
1074 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001075 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001076}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001077#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001078
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001079
1080static char posix_rename__doc__[] =
1081"rename(old, new) -> None\n\
1082Rename a file or directory.";
1083
Barry Warsaw53699e91996-12-10 23:23:01 +00001084static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001085posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001086{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001087 return posix_2str(args, "ss:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001088}
1089
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001090
1091static char posix_rmdir__doc__[] =
1092"rmdir(path) -> None\n\
1093Remove a directory.";
1094
Barry Warsaw53699e91996-12-10 23:23:01 +00001095static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001096posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001097{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001098 return posix_1str(args, "s:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001099}
1100
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001101
1102static char posix_stat__doc__[] =
1103"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1104Perform a stat system call on the given path.";
1105
Barry Warsaw53699e91996-12-10 23:23:01 +00001106static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001107posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001108{
Fred Drake699f3522000-06-29 21:12:41 +00001109 return posix_do_stat(self, args, "s:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001110}
1111
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001112
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001113#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001114static char posix_system__doc__[] =
1115"system(command) -> exit_status\n\
1116Execute the command (a string) in a subshell.";
1117
Barry Warsaw53699e91996-12-10 23:23:01 +00001118static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001119posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001120{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001121 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001122 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001123 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001124 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001125 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001126 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001127 Py_END_ALLOW_THREADS
1128 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001129}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001130#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001131
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001132
1133static char posix_umask__doc__[] =
1134"umask(new_mask) -> old_mask\n\
1135Set the current numeric umask and return the previous umask.";
1136
Barry Warsaw53699e91996-12-10 23:23:01 +00001137static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001138posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001139{
1140 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001141 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001142 return NULL;
1143 i = umask(i);
1144 if (i < 0)
1145 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001146 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001147}
1148
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001149
1150static char posix_unlink__doc__[] =
1151"unlink(path) -> None\n\
1152Remove a file (same as remove(path)).";
1153
1154static char posix_remove__doc__[] =
1155"remove(path) -> None\n\
1156Remove a file (same as unlink(path)).";
1157
Barry Warsaw53699e91996-12-10 23:23:01 +00001158static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001159posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001160{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001161 return posix_1str(args, "s:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001162}
1163
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001164
Guido van Rossumb6775db1994-08-01 11:34:53 +00001165#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001166static char posix_uname__doc__[] =
1167"uname() -> (sysname, nodename, release, version, machine)\n\
1168Return a tuple identifying the current operating system.";
1169
Barry Warsaw53699e91996-12-10 23:23:01 +00001170static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001171posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001172{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001173 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001174 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001175 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001176 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001177 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001178 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001179 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001180 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001181 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001182 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001183 u.sysname,
1184 u.nodename,
1185 u.release,
1186 u.version,
1187 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001188}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001189#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001190
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001191
1192static char posix_utime__doc__[] =
1193"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001194utime(path, None) -> None\n\
1195Set the access and modified time of the file to the given values. If the\n\
1196second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001197
Barry Warsaw53699e91996-12-10 23:23:01 +00001198static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001199posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001200{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001201 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001202 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001203 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001204 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001205
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001206/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001207#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001208 struct utimbuf buf;
1209#define ATIME buf.actime
1210#define MTIME buf.modtime
1211#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001212#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001213 time_t buf[2];
1214#define ATIME buf[0]
1215#define MTIME buf[1]
1216#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001217#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001218
Barry Warsaw3cef8562000-05-01 16:17:24 +00001219 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001220 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001221 if (arg == Py_None) {
1222 /* optional time values not given */
1223 Py_BEGIN_ALLOW_THREADS
1224 res = utime(path, NULL);
1225 Py_END_ALLOW_THREADS
1226 }
1227 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1228 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001229 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001230 return NULL;
1231 }
1232 else {
1233 ATIME = atime;
1234 MTIME = mtime;
1235 Py_BEGIN_ALLOW_THREADS
1236 res = utime(path, UTIME_ARG);
1237 Py_END_ALLOW_THREADS
1238 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001239 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001240 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001241 Py_INCREF(Py_None);
1242 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001243#undef UTIME_ARG
1244#undef ATIME
1245#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001246}
1247
Guido van Rossum85e3b011991-06-03 12:42:10 +00001248
Guido van Rossum3b066191991-06-04 19:40:25 +00001249/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001250
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001251static char posix__exit__doc__[] =
1252"_exit(status)\n\
1253Exit to the system with specified status, without normal exit processing.";
1254
Barry Warsaw53699e91996-12-10 23:23:01 +00001255static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001256posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001257{
1258 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001259 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001260 return NULL;
1261 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001262 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001263}
1264
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001265
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001266#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001267static char posix_execv__doc__[] =
1268"execv(path, args)\n\
1269Execute an executable path with arguments, replacing current process.\n\
1270\n\
1271 path: path of executable file\n\
1272 args: tuple or list of strings";
1273
Barry Warsaw53699e91996-12-10 23:23:01 +00001274static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001275posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001276{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001277 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001278 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001279 char **argvlist;
1280 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001281 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001282
Guido van Rossum89b33251993-10-22 14:26:06 +00001283 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001284 argv is a list or tuple of strings. */
1285
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001286 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001287 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001288 if (PyList_Check(argv)) {
1289 argc = PyList_Size(argv);
1290 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001291 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001292 else if (PyTuple_Check(argv)) {
1293 argc = PyTuple_Size(argv);
1294 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001295 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001296 else {
Fred Drake661ea262000-10-24 19:57:45 +00001297 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001298 return NULL;
1299 }
1300
1301 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001302 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001303 return NULL;
1304 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001305
Barry Warsaw53699e91996-12-10 23:23:01 +00001306 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001307 if (argvlist == NULL)
1308 return NULL;
1309 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001310 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1311 PyMem_DEL(argvlist);
Guido van Rossum50422b42000-04-26 20:34:28 +00001312 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001313 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001314 return NULL;
1315
Guido van Rossum85e3b011991-06-03 12:42:10 +00001316 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001317 }
1318 argvlist[argc] = NULL;
1319
Guido van Rossumb6775db1994-08-01 11:34:53 +00001320#ifdef BAD_EXEC_PROTOTYPES
1321 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001322#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001323 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001324#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001325
Guido van Rossum85e3b011991-06-03 12:42:10 +00001326 /* If we get here it's definitely an error */
1327
Barry Warsaw53699e91996-12-10 23:23:01 +00001328 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001329 return posix_error();
1330}
1331
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001332
1333static char posix_execve__doc__[] =
1334"execve(path, args, env)\n\
1335Execute a path with arguments and environment, replacing current process.\n\
1336\n\
1337 path: path of executable file\n\
1338 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001339 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001340
Barry Warsaw53699e91996-12-10 23:23:01 +00001341static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001342posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001343{
1344 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001345 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001346 char **argvlist;
1347 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001348 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001349 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001350 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001351
1352 /* execve has three arguments: (path, argv, env), where
1353 argv is a list or tuple of strings and env is a dictionary
1354 like posix.environ. */
1355
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001356 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001357 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001358 if (PyList_Check(argv)) {
1359 argc = PyList_Size(argv);
1360 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001361 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001362 else if (PyTuple_Check(argv)) {
1363 argc = PyTuple_Size(argv);
1364 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001365 }
1366 else {
Fred Drake661ea262000-10-24 19:57:45 +00001367 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001368 return NULL;
1369 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001370 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001371 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001372 return NULL;
1373 }
1374
Guido van Rossum50422b42000-04-26 20:34:28 +00001375 if (argc == 0) {
1376 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001377 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001378 return NULL;
1379 }
1380
Barry Warsaw53699e91996-12-10 23:23:01 +00001381 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001382 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001383 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001384 return NULL;
1385 }
1386 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001387 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001388 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001389 &argvlist[i]))
1390 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001391 goto fail_1;
1392 }
1393 }
1394 argvlist[argc] = NULL;
1395
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001396 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001397 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001398 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001399 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001400 goto fail_1;
1401 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001402 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001403 keys = PyMapping_Keys(env);
1404 vals = PyMapping_Values(env);
1405 if (!keys || !vals)
1406 goto fail_2;
1407
1408 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001409 char *p, *k, *v;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001410
1411 key = PyList_GetItem(keys, pos);
1412 val = PyList_GetItem(vals, pos);
1413 if (!key || !val)
1414 goto fail_2;
1415
Fred Drake661ea262000-10-24 19:57:45 +00001416 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1417 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001418 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001419 goto fail_2;
1420 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001421
1422#if defined(PYOS_OS2)
1423 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1424 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1425#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001426 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001427 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001428 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001429 goto fail_2;
1430 }
1431 sprintf(p, "%s=%s", k, v);
1432 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001433#if defined(PYOS_OS2)
1434 }
1435#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001436 }
1437 envlist[envc] = 0;
1438
Guido van Rossumb6775db1994-08-01 11:34:53 +00001439
1440#ifdef BAD_EXEC_PROTOTYPES
1441 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001442#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001443 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001444#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001445
1446 /* If we get here it's definitely an error */
1447
1448 (void) posix_error();
1449
1450 fail_2:
1451 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001452 PyMem_DEL(envlist[envc]);
1453 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001454 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001455 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001456 Py_XDECREF(vals);
1457 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001458 return NULL;
1459}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001460#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001461
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001462
Guido van Rossuma1065681999-01-25 23:20:23 +00001463#ifdef HAVE_SPAWNV
1464static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001465"spawnv(mode, path, args)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001466Execute an executable path with arguments, replacing current process.\n\
1467\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001468 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001469 path: path of executable file\n\
1470 args: tuple or list of strings";
1471
1472static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001473posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001474{
1475 char *path;
1476 PyObject *argv;
1477 char **argvlist;
1478 int mode, i, argc;
Fred Drake699f3522000-06-29 21:12:41 +00001479 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001480 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001481
1482 /* spawnv has three arguments: (mode, path, argv), where
1483 argv is a list or tuple of strings. */
1484
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001485 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001486 return NULL;
1487 if (PyList_Check(argv)) {
1488 argc = PyList_Size(argv);
1489 getitem = PyList_GetItem;
1490 }
1491 else if (PyTuple_Check(argv)) {
1492 argc = PyTuple_Size(argv);
1493 getitem = PyTuple_GetItem;
1494 }
1495 else {
Fred Drake661ea262000-10-24 19:57:45 +00001496 PyErr_SetString(PyExc_TypeError, "spawmv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001497 return NULL;
1498 }
1499
1500 argvlist = PyMem_NEW(char *, argc+1);
1501 if (argvlist == NULL)
1502 return NULL;
1503 for (i = 0; i < argc; i++) {
1504 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1505 PyMem_DEL(argvlist);
Fred Drake137507e2000-06-01 02:02:46 +00001506 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001507 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001508 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001509 }
1510 }
1511 argvlist[argc] = NULL;
1512
Guido van Rossum246bc171999-02-01 23:54:31 +00001513 if (mode == _OLD_P_OVERLAY)
1514 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001515 spawnval = _spawnv(mode, path, argvlist);
Guido van Rossuma1065681999-01-25 23:20:23 +00001516
1517 PyMem_DEL(argvlist);
1518
Fred Drake699f3522000-06-29 21:12:41 +00001519 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001520 return posix_error();
1521 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001522#if SIZEOF_LONG == SIZEOF_VOID_P
1523 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001524#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001525 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001526#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001527}
1528
1529
1530static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001531"spawnve(mode, path, args, env)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001532Execute a path with arguments and environment, replacing current process.\n\
1533\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001534 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001535 path: path of executable file\n\
1536 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001537 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001538
1539static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001540posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001541{
1542 char *path;
1543 PyObject *argv, *env;
1544 char **argvlist;
1545 char **envlist;
1546 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1547 int mode, i, pos, argc, envc;
Fred Drake699f3522000-06-29 21:12:41 +00001548 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001549 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001550
1551 /* spawnve has four arguments: (mode, path, argv, env), where
1552 argv is a list or tuple of strings and env is a dictionary
1553 like posix.environ. */
1554
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001555 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001556 return NULL;
1557 if (PyList_Check(argv)) {
1558 argc = PyList_Size(argv);
1559 getitem = PyList_GetItem;
1560 }
1561 else if (PyTuple_Check(argv)) {
1562 argc = PyTuple_Size(argv);
1563 getitem = PyTuple_GetItem;
1564 }
1565 else {
Fred Drake661ea262000-10-24 19:57:45 +00001566 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001567 return NULL;
1568 }
1569 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001570 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001571 return NULL;
1572 }
1573
1574 argvlist = PyMem_NEW(char *, argc+1);
1575 if (argvlist == NULL) {
1576 PyErr_NoMemory();
1577 return NULL;
1578 }
1579 for (i = 0; i < argc; i++) {
1580 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001581 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001582 &argvlist[i]))
1583 {
1584 goto fail_1;
1585 }
1586 }
1587 argvlist[argc] = NULL;
1588
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001589 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001590 envlist = PyMem_NEW(char *, i + 1);
1591 if (envlist == NULL) {
1592 PyErr_NoMemory();
1593 goto fail_1;
1594 }
1595 envc = 0;
1596 keys = PyMapping_Keys(env);
1597 vals = PyMapping_Values(env);
1598 if (!keys || !vals)
1599 goto fail_2;
1600
1601 for (pos = 0; pos < i; pos++) {
1602 char *p, *k, *v;
1603
1604 key = PyList_GetItem(keys, pos);
1605 val = PyList_GetItem(vals, pos);
1606 if (!key || !val)
1607 goto fail_2;
1608
Fred Drake661ea262000-10-24 19:57:45 +00001609 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1610 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001611 {
1612 goto fail_2;
1613 }
1614 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1615 if (p == NULL) {
1616 PyErr_NoMemory();
1617 goto fail_2;
1618 }
1619 sprintf(p, "%s=%s", k, v);
1620 envlist[envc++] = p;
1621 }
1622 envlist[envc] = 0;
1623
Guido van Rossum246bc171999-02-01 23:54:31 +00001624 if (mode == _OLD_P_OVERLAY)
1625 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001626 spawnval = _spawnve(mode, path, argvlist, envlist);
1627 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001628 (void) posix_error();
1629 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001630#if SIZEOF_LONG == SIZEOF_VOID_P
1631 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001632#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001633 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001634#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001635
1636 fail_2:
1637 while (--envc >= 0)
1638 PyMem_DEL(envlist[envc]);
1639 PyMem_DEL(envlist);
1640 fail_1:
1641 PyMem_DEL(argvlist);
1642 Py_XDECREF(vals);
1643 Py_XDECREF(keys);
1644 return res;
1645}
1646#endif /* HAVE_SPAWNV */
1647
1648
Guido van Rossumad0ee831995-03-01 10:34:45 +00001649#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001650static char posix_fork__doc__[] =
1651"fork() -> pid\n\
1652Fork a child process.\n\
1653\n\
1654Return 0 to child process and PID of child to parent process.";
1655
Barry Warsaw53699e91996-12-10 23:23:01 +00001656static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001657posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001658{
1659 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001660 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001661 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001662 pid = fork();
1663 if (pid == -1)
1664 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001665 if (pid == 0)
1666 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001667 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001668}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001669#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001670
Fred Drake8cef4cf2000-06-28 16:40:38 +00001671#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1672#ifdef HAVE_PTY_H
1673#include <pty.h>
1674#else
1675#ifdef HAVE_LIBUTIL_H
1676#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001677#endif /* HAVE_LIBUTIL_H */
1678#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001679#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001680
Thomas Wouters70c21a12000-07-14 14:28:33 +00001681#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001682static char posix_openpty__doc__[] =
1683"openpty() -> (master_fd, slave_fd)\n\
1684Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1685
1686static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001687posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001688{
1689 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001690#ifndef HAVE_OPENPTY
1691 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001692#endif
1693
Fred Drake8cef4cf2000-06-28 16:40:38 +00001694 if (!PyArg_ParseTuple(args, ":openpty"))
1695 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001696
1697#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001698 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1699 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001700#else
1701 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1702 if (slave_name == NULL)
1703 return posix_error();
1704
1705 slave_fd = open(slave_name, O_RDWR);
1706 if (slave_fd < 0)
1707 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001708#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001709
Fred Drake8cef4cf2000-06-28 16:40:38 +00001710 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001711
Fred Drake8cef4cf2000-06-28 16:40:38 +00001712}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001713#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001714
1715#ifdef HAVE_FORKPTY
1716static char posix_forkpty__doc__[] =
1717"forkpty() -> (pid, master_fd)\n\
1718Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1719Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1720To both, return fd of newly opened pseudo-terminal.\n";
1721
1722static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001723posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001724{
1725 int master_fd, pid;
1726
1727 if (!PyArg_ParseTuple(args, ":forkpty"))
1728 return NULL;
1729 pid = forkpty(&master_fd, NULL, NULL, NULL);
1730 if (pid == -1)
1731 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001732 if (pid == 0)
1733 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001734 return Py_BuildValue("(ii)", pid, master_fd);
1735}
1736#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001737
Guido van Rossumad0ee831995-03-01 10:34:45 +00001738#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001739static char posix_getegid__doc__[] =
1740"getegid() -> egid\n\
1741Return the current process's effective group id.";
1742
Barry Warsaw53699e91996-12-10 23:23:01 +00001743static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001744posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001745{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001746 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001747 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001748 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001749}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001750#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001751
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001752
Guido van Rossumad0ee831995-03-01 10:34:45 +00001753#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001754static char posix_geteuid__doc__[] =
1755"geteuid() -> euid\n\
1756Return the current process's effective user id.";
1757
Barry Warsaw53699e91996-12-10 23:23:01 +00001758static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001759posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001760{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001761 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001762 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001763 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001764}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001765#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001766
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001767
Guido van Rossumad0ee831995-03-01 10:34:45 +00001768#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001769static char posix_getgid__doc__[] =
1770"getgid() -> gid\n\
1771Return the current process's group id.";
1772
Barry Warsaw53699e91996-12-10 23:23:01 +00001773static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001774posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001775{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001776 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001777 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001778 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001779}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001780#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001781
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001782
1783static char posix_getpid__doc__[] =
1784"getpid() -> pid\n\
1785Return the current process id";
1786
Barry Warsaw53699e91996-12-10 23:23:01 +00001787static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001788posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001789{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001790 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001791 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001792 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001793}
1794
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001795
Fred Drakec9680921999-12-13 16:37:25 +00001796#ifdef HAVE_GETGROUPS
1797static char posix_getgroups__doc__[] = "\
1798getgroups() -> list of group IDs\n\
1799Return list of supplemental group IDs for the process.";
1800
1801static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001802posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00001803{
1804 PyObject *result = NULL;
1805
1806 if (PyArg_ParseTuple(args, ":getgroups")) {
1807#ifdef NGROUPS_MAX
1808#define MAX_GROUPS NGROUPS_MAX
1809#else
1810 /* defined to be 16 on Solaris7, so this should be a small number */
1811#define MAX_GROUPS 64
1812#endif
1813 gid_t grouplist[MAX_GROUPS];
1814 int n;
1815
1816 n = getgroups(MAX_GROUPS, grouplist);
1817 if (n < 0)
1818 posix_error();
1819 else {
1820 result = PyList_New(n);
1821 if (result != NULL) {
1822 PyObject *o;
1823 int i;
1824 for (i = 0; i < n; ++i) {
1825 o = PyInt_FromLong((long)grouplist[i]);
1826 if (o == NULL) {
1827 Py_DECREF(result);
1828 result = NULL;
1829 break;
1830 }
1831 PyList_SET_ITEM(result, i, o);
1832 }
1833 }
1834 }
1835 }
1836 return result;
1837}
1838#endif
1839
Guido van Rossumb6775db1994-08-01 11:34:53 +00001840#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001841static char posix_getpgrp__doc__[] =
1842"getpgrp() -> pgrp\n\
1843Return the current process group id.";
1844
Barry Warsaw53699e91996-12-10 23:23:01 +00001845static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001846posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00001847{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001848 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00001849 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001850#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00001851 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001852#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00001853 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001854#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00001855}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001856#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00001857
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001858
Guido van Rossumb6775db1994-08-01 11:34:53 +00001859#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001860static char posix_setpgrp__doc__[] =
1861"setpgrp() -> None\n\
1862Make this process a session leader.";
1863
Barry Warsaw53699e91996-12-10 23:23:01 +00001864static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001865posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00001866{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001867 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00001868 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00001869#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00001870 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001871#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001872 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001873#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00001874 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001875 Py_INCREF(Py_None);
1876 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00001877}
1878
Guido van Rossumb6775db1994-08-01 11:34:53 +00001879#endif /* HAVE_SETPGRP */
1880
Guido van Rossumad0ee831995-03-01 10:34:45 +00001881#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001882static char posix_getppid__doc__[] =
1883"getppid() -> ppid\n\
1884Return the parent's process id.";
1885
Barry Warsaw53699e91996-12-10 23:23:01 +00001886static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001887posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001888{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001889 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001890 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001891 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001892}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001893#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001894
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001895
Fred Drake12c6e2d1999-12-14 21:25:03 +00001896#ifdef HAVE_GETLOGIN
1897static char posix_getlogin__doc__[] = "\
1898getlogin() -> string\n\
1899Return the actual login name.";
1900
1901static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001902posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00001903{
1904 PyObject *result = NULL;
1905
1906 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00001907 char *name;
1908 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00001909
Fred Drakea30680b2000-12-06 21:24:28 +00001910 errno = 0;
1911 name = getlogin();
1912 if (name == NULL) {
1913 if (errno)
1914 posix_error();
1915 else
1916 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00001917 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00001918 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00001919 else
1920 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00001921 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00001922 }
1923 return result;
1924}
1925#endif
1926
Guido van Rossumad0ee831995-03-01 10:34:45 +00001927#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001928static char posix_getuid__doc__[] =
1929"getuid() -> uid\n\
1930Return the current process's user id.";
1931
Barry Warsaw53699e91996-12-10 23:23:01 +00001932static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001933posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001934{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001935 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001936 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001937 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001938}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001939#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001940
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001941
Guido van Rossumad0ee831995-03-01 10:34:45 +00001942#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001943static char posix_kill__doc__[] =
1944"kill(pid, sig) -> None\n\
1945Kill a process with a signal.";
1946
Barry Warsaw53699e91996-12-10 23:23:01 +00001947static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001948posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001949{
1950 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001951 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001952 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001953#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001954 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
1955 APIRET rc;
1956 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001957 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001958
1959 } else if (sig == XCPT_SIGNAL_KILLPROC) {
1960 APIRET rc;
1961 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001962 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001963
1964 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001965 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001966#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00001967 if (kill(pid, sig) == -1)
1968 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001969#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001970 Py_INCREF(Py_None);
1971 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001972}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001973#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001974
Guido van Rossumc0125471996-06-28 18:55:32 +00001975#ifdef HAVE_PLOCK
1976
1977#ifdef HAVE_SYS_LOCK_H
1978#include <sys/lock.h>
1979#endif
1980
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001981static char posix_plock__doc__[] =
1982"plock(op) -> None\n\
1983Lock program segments into memory.";
1984
Barry Warsaw53699e91996-12-10 23:23:01 +00001985static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001986posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00001987{
1988 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001989 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00001990 return NULL;
1991 if (plock(op) == -1)
1992 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001993 Py_INCREF(Py_None);
1994 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00001995}
1996#endif
1997
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001998
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001999#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002000static char posix_popen__doc__[] =
2001"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2002Open a pipe to/from a command returning a file object.";
2003
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002004#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002005static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002006async_system(const char *command)
2007{
2008 char *p, errormsg[256], args[1024];
2009 RESULTCODES rcodes;
2010 APIRET rc;
2011 char *shell = getenv("COMSPEC");
2012 if (!shell)
2013 shell = "cmd";
2014
2015 strcpy(args, shell);
2016 p = &args[ strlen(args)+1 ];
2017 strcpy(p, "/c ");
2018 strcat(p, command);
2019 p += strlen(p) + 1;
2020 *p = '\0';
2021
2022 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002023 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002024 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002025 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002026 &rcodes, shell);
2027 return rc;
2028}
2029
Guido van Rossumd48f2521997-12-05 22:19:34 +00002030static FILE *
2031popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002032{
2033 HFILE rhan, whan;
2034 FILE *retfd = NULL;
2035 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2036
Guido van Rossumd48f2521997-12-05 22:19:34 +00002037 if (rc != NO_ERROR) {
2038 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002039 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002040 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002041
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002042 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2043 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002044
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002045 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2046 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002047
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002048 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2049 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002050
2051 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002052 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002053 }
2054
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002055 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2056 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002057
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002058 close(oldfd); /* And Close Saved STDOUT Handle */
2059 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002060
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002061 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2062 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002063
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002064 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2065 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002066
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002067 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2068 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002069
2070 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002071 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002072 }
2073
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002074 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2075 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002076
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002077 close(oldfd); /* And Close Saved STDIN Handle */
2078 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002079
Guido van Rossumd48f2521997-12-05 22:19:34 +00002080 } else {
2081 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002082 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002083 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002084}
2085
2086static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002087posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002088{
2089 char *name;
2090 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002091 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002092 FILE *fp;
2093 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002094 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002095 return NULL;
2096 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002097 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002098 Py_END_ALLOW_THREADS
2099 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002100 return os2_error(err);
2101
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002102 f = PyFile_FromFile(fp, name, mode, fclose);
2103 if (f != NULL)
2104 PyFile_SetBufSize(f, bufsize);
2105 return f;
2106}
2107
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002108#elif defined(MS_WIN32)
2109
2110/*
2111 * Portable 'popen' replacement for Win32.
2112 *
2113 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2114 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00002115 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002116 */
2117
2118#include <malloc.h>
2119#include <io.h>
2120#include <fcntl.h>
2121
2122/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2123#define POPEN_1 1
2124#define POPEN_2 2
2125#define POPEN_3 3
2126#define POPEN_4 4
2127
2128static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002129static int _PyPclose(FILE *file);
2130
2131/*
2132 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00002133 * for use when retrieving the process exit code. See _PyPclose() below
2134 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002135 */
2136static PyObject *_PyPopenProcs = NULL;
2137
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002138
2139/* popen that works from a GUI.
2140 *
2141 * The result of this function is a pipe (file) connected to the
2142 * processes stdin or stdout, depending on the requested mode.
2143 */
2144
2145static PyObject *
2146posix_popen(PyObject *self, PyObject *args)
2147{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002148 PyObject *f, *s;
2149 int tm = 0;
2150
2151 char *cmdstring;
2152 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002153 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002154 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002155 return NULL;
2156
2157 s = PyTuple_New(0);
2158
2159 if (*mode == 'r')
2160 tm = _O_RDONLY;
2161 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00002162 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002163 return NULL;
2164 } else
2165 tm = _O_WRONLY;
2166
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002167 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002168 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002169 return NULL;
2170 }
2171
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002172 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002173 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002174 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002175 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002176 else
2177 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2178
2179 return f;
2180}
2181
2182/* Variation on win32pipe.popen
2183 *
2184 * The result of this function is a pipe (file) connected to the
2185 * process's stdin, and a pipe connected to the process's stdout.
2186 */
2187
2188static PyObject *
2189win32_popen2(PyObject *self, PyObject *args)
2190{
2191 PyObject *f;
2192 int tm=0;
2193
2194 char *cmdstring;
2195 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002196 int bufsize = -1;
2197 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002198 return NULL;
2199
2200 if (*mode == 't')
2201 tm = _O_TEXT;
2202 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002203 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002204 return NULL;
2205 } else
2206 tm = _O_BINARY;
2207
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002208 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002209 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002210 return NULL;
2211 }
2212
2213 f = _PyPopen(cmdstring, tm, POPEN_2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002214
2215 return f;
2216}
2217
2218/*
2219 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002220 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002221 * The result of this function is 3 pipes - the process's stdin,
2222 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002223 */
2224
2225static PyObject *
2226win32_popen3(PyObject *self, PyObject *args)
2227{
2228 PyObject *f;
2229 int tm = 0;
2230
2231 char *cmdstring;
2232 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002233 int bufsize = -1;
2234 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002235 return NULL;
2236
2237 if (*mode == 't')
2238 tm = _O_TEXT;
2239 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002240 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002241 return NULL;
2242 } else
2243 tm = _O_BINARY;
2244
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002245 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002246 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002247 return NULL;
2248 }
2249
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002250 f = _PyPopen(cmdstring, tm, POPEN_3);
2251
2252 return f;
2253}
2254
2255/*
2256 * Variation on win32pipe.popen
2257 *
2258 * The result of this function is 2 pipes - the processes stdin,
2259 * and stdout+stderr combined as a single pipe.
2260 */
2261
2262static PyObject *
2263win32_popen4(PyObject *self, PyObject *args)
2264{
2265 PyObject *f;
2266 int tm = 0;
2267
2268 char *cmdstring;
2269 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002270 int bufsize = -1;
2271 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002272 return NULL;
2273
2274 if (*mode == 't')
2275 tm = _O_TEXT;
2276 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002277 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002278 return NULL;
2279 } else
2280 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002281
2282 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002283 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002284 return NULL;
2285 }
2286
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002287 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002288
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002289 return f;
2290}
2291
Mark Hammond08501372001-01-31 07:30:29 +00002292static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00002293_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002294 HANDLE hStdin,
2295 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00002296 HANDLE hStderr,
2297 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002298{
2299 PROCESS_INFORMATION piProcInfo;
2300 STARTUPINFO siStartInfo;
2301 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00002302 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002303 int i;
2304 int x;
2305
2306 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
2307 s1 = (char *)_alloca(i);
2308 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2309 return x;
2310 if (GetVersion() < 0x80000000) {
2311 /*
2312 * NT/2000
2313 */
2314 x = i + strlen(s3) + strlen(cmdstring) + 1;
2315 s2 = (char *)_alloca(x);
2316 ZeroMemory(s2, x);
2317 sprintf(s2, "%s%s%s", s1, s3, cmdstring);
2318 }
2319 else {
2320 /*
2321 * Oh gag, we're on Win9x. Use the workaround listed in
2322 * KB: Q150956
2323 */
Mark Hammond08501372001-01-31 07:30:29 +00002324 char modulepath[_MAX_PATH];
2325 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002326 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2327 for (i = x = 0; modulepath[i]; i++)
2328 if (modulepath[i] == '\\')
2329 x = i+1;
2330 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00002331 /* Create the full-name to w9xpopen, so we can test it exists */
2332 strncat(modulepath,
2333 szConsoleSpawn,
2334 (sizeof(modulepath)/sizeof(modulepath[0]))
2335 -strlen(modulepath));
2336 if (stat(modulepath, &statinfo) != 0) {
2337 /* Eeek - file-not-found - possibly an embedding
2338 situation - see if we can locate it in sys.prefix
2339 */
2340 strncpy(modulepath,
2341 Py_GetExecPrefix(),
2342 sizeof(modulepath)/sizeof(modulepath[0]));
2343 if (modulepath[strlen(modulepath)-1] != '\\')
2344 strcat(modulepath, "\\");
2345 strncat(modulepath,
2346 szConsoleSpawn,
2347 (sizeof(modulepath)/sizeof(modulepath[0]))
2348 -strlen(modulepath));
2349 /* No where else to look - raise an easily identifiable
2350 error, rather than leaving Windows to report
2351 "file not found" - as the user is probably blissfully
2352 unaware this shim EXE is used, and it will confuse them.
2353 (well, it confused me for a while ;-)
2354 */
2355 if (stat(modulepath, &statinfo) != 0) {
2356 PyErr_Format(PyExc_RuntimeError,
2357 "Can not locate '%s' which is needed "
2358 "for popen to work on this platform.",
2359 szConsoleSpawn);
2360 return FALSE;
2361 }
2362 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002363 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2364 strlen(modulepath) +
2365 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00002366
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002367 s2 = (char *)_alloca(x);
2368 ZeroMemory(s2, x);
2369 sprintf(
2370 s2,
Mark Hammond08501372001-01-31 07:30:29 +00002371 "%s \"%s%s%s\"",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002372 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002373 s1,
2374 s3,
2375 cmdstring);
2376 }
2377 }
2378
2379 /* Could be an else here to try cmd.exe / command.com in the path
2380 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00002381 else {
2382 PyErr_SetString(PyExc_RuntimeError, "Can not locate a COMSPEC environment variable to use as the shell");
2383 return FALSE;
2384 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002385
2386 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2387 siStartInfo.cb = sizeof(STARTUPINFO);
2388 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2389 siStartInfo.hStdInput = hStdin;
2390 siStartInfo.hStdOutput = hStdout;
2391 siStartInfo.hStdError = hStderr;
2392 siStartInfo.wShowWindow = SW_HIDE;
2393
2394 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002395 s2,
2396 NULL,
2397 NULL,
2398 TRUE,
2399 CREATE_NEW_CONSOLE,
2400 NULL,
2401 NULL,
2402 &siStartInfo,
2403 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002404 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002405 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002406
Mark Hammondb37a3732000-08-14 04:47:33 +00002407 /* Return process handle */
2408 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002409 return TRUE;
2410 }
Mark Hammond08501372001-01-31 07:30:29 +00002411 win32_error("CreateProcess", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002412 return FALSE;
2413}
2414
2415/* The following code is based off of KB: Q190351 */
2416
2417static PyObject *
2418_PyPopen(char *cmdstring, int mode, int n)
2419{
2420 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2421 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00002422 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002423
2424 SECURITY_ATTRIBUTES saAttr;
2425 BOOL fSuccess;
2426 int fd1, fd2, fd3;
2427 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00002428 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002429 PyObject *f;
2430
2431 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2432 saAttr.bInheritHandle = TRUE;
2433 saAttr.lpSecurityDescriptor = NULL;
2434
2435 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2436 return win32_error("CreatePipe", NULL);
2437
2438 /* Create new output read handle and the input write handle. Set
2439 * the inheritance properties to FALSE. Otherwise, the child inherits
2440 * the these handles; resulting in non-closeable handles to the pipes
2441 * being created. */
2442 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002443 GetCurrentProcess(), &hChildStdinWrDup, 0,
2444 FALSE,
2445 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002446 if (!fSuccess)
2447 return win32_error("DuplicateHandle", NULL);
2448
2449 /* Close the inheritable version of ChildStdin
2450 that we're using. */
2451 CloseHandle(hChildStdinWr);
2452
2453 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2454 return win32_error("CreatePipe", NULL);
2455
2456 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002457 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2458 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002459 if (!fSuccess)
2460 return win32_error("DuplicateHandle", NULL);
2461
2462 /* Close the inheritable version of ChildStdout
2463 that we're using. */
2464 CloseHandle(hChildStdoutRd);
2465
2466 if (n != POPEN_4) {
2467 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2468 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002469 fSuccess = DuplicateHandle(GetCurrentProcess(),
2470 hChildStderrRd,
2471 GetCurrentProcess(),
2472 &hChildStderrRdDup, 0,
2473 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002474 if (!fSuccess)
2475 return win32_error("DuplicateHandle", NULL);
2476 /* Close the inheritable version of ChildStdErr that we're using. */
2477 CloseHandle(hChildStderrRd);
2478 }
2479
2480 switch (n) {
2481 case POPEN_1:
2482 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2483 case _O_WRONLY | _O_TEXT:
2484 /* Case for writing to child Stdin in text mode. */
2485 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2486 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002487 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002488 PyFile_SetBufSize(f, 0);
2489 /* We don't care about these pipes anymore, so close them. */
2490 CloseHandle(hChildStdoutRdDup);
2491 CloseHandle(hChildStderrRdDup);
2492 break;
2493
2494 case _O_RDONLY | _O_TEXT:
2495 /* Case for reading from child Stdout in text mode. */
2496 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2497 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002498 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002499 PyFile_SetBufSize(f, 0);
2500 /* We don't care about these pipes anymore, so close them. */
2501 CloseHandle(hChildStdinWrDup);
2502 CloseHandle(hChildStderrRdDup);
2503 break;
2504
2505 case _O_RDONLY | _O_BINARY:
2506 /* Case for readinig from child Stdout in binary mode. */
2507 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2508 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002509 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002510 PyFile_SetBufSize(f, 0);
2511 /* We don't care about these pipes anymore, so close them. */
2512 CloseHandle(hChildStdinWrDup);
2513 CloseHandle(hChildStderrRdDup);
2514 break;
2515
2516 case _O_WRONLY | _O_BINARY:
2517 /* Case for writing to child Stdin in binary mode. */
2518 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2519 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002520 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002521 PyFile_SetBufSize(f, 0);
2522 /* We don't care about these pipes anymore, so close them. */
2523 CloseHandle(hChildStdoutRdDup);
2524 CloseHandle(hChildStderrRdDup);
2525 break;
2526 }
Mark Hammondb37a3732000-08-14 04:47:33 +00002527 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002528 break;
2529
2530 case POPEN_2:
2531 case POPEN_4:
2532 {
2533 char *m1, *m2;
2534 PyObject *p1, *p2;
2535
2536 if (mode && _O_TEXT) {
2537 m1 = "r";
2538 m2 = "w";
2539 } else {
2540 m1 = "rb";
2541 m2 = "wb";
2542 }
2543
2544 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2545 f1 = _fdopen(fd1, m2);
2546 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2547 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002548 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002549 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00002550 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002551 PyFile_SetBufSize(p2, 0);
2552
2553 if (n != 4)
2554 CloseHandle(hChildStderrRdDup);
2555
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002556 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00002557 Py_XDECREF(p1);
2558 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00002559 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002560 break;
2561 }
2562
2563 case POPEN_3:
2564 {
2565 char *m1, *m2;
2566 PyObject *p1, *p2, *p3;
2567
2568 if (mode && _O_TEXT) {
2569 m1 = "r";
2570 m2 = "w";
2571 } else {
2572 m1 = "rb";
2573 m2 = "wb";
2574 }
2575
2576 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2577 f1 = _fdopen(fd1, m2);
2578 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2579 f2 = _fdopen(fd2, m1);
2580 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2581 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002582 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00002583 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
2584 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002585 PyFile_SetBufSize(p1, 0);
2586 PyFile_SetBufSize(p2, 0);
2587 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002588 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00002589 Py_XDECREF(p1);
2590 Py_XDECREF(p2);
2591 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00002592 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002593 break;
2594 }
2595 }
2596
2597 if (n == POPEN_4) {
2598 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002599 hChildStdinRd,
2600 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002601 hChildStdoutWr,
2602 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002603 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002604 }
2605 else {
2606 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002607 hChildStdinRd,
2608 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002609 hChildStderrWr,
2610 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002611 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002612 }
2613
Mark Hammondb37a3732000-08-14 04:47:33 +00002614 /*
2615 * Insert the files we've created into the process dictionary
2616 * all referencing the list with the process handle and the
2617 * initial number of files (see description below in _PyPclose).
2618 * Since if _PyPclose later tried to wait on a process when all
2619 * handles weren't closed, it could create a deadlock with the
2620 * child, we spend some energy here to try to ensure that we
2621 * either insert all file handles into the dictionary or none
2622 * at all. It's a little clumsy with the various popen modes
2623 * and variable number of files involved.
2624 */
2625 if (!_PyPopenProcs) {
2626 _PyPopenProcs = PyDict_New();
2627 }
2628
2629 if (_PyPopenProcs) {
2630 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
2631 int ins_rc[3];
2632
2633 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2634 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2635
2636 procObj = PyList_New(2);
2637 hProcessObj = PyLong_FromVoidPtr(hProcess);
2638 intObj = PyInt_FromLong(file_count);
2639
2640 if (procObj && hProcessObj && intObj) {
2641 PyList_SetItem(procObj,0,hProcessObj);
2642 PyList_SetItem(procObj,1,intObj);
2643
2644 fileObj[0] = PyLong_FromVoidPtr(f1);
2645 if (fileObj[0]) {
2646 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2647 fileObj[0],
2648 procObj);
2649 }
2650 if (file_count >= 2) {
2651 fileObj[1] = PyLong_FromVoidPtr(f2);
2652 if (fileObj[1]) {
2653 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2654 fileObj[1],
2655 procObj);
2656 }
2657 }
2658 if (file_count >= 3) {
2659 fileObj[2] = PyLong_FromVoidPtr(f3);
2660 if (fileObj[2]) {
2661 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2662 fileObj[2],
2663 procObj);
2664 }
2665 }
2666
2667 if (ins_rc[0] < 0 || !fileObj[0] ||
2668 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2669 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
2670 /* Something failed - remove any dictionary
2671 * entries that did make it.
2672 */
2673 if (!ins_rc[0] && fileObj[0]) {
2674 PyDict_DelItem(_PyPopenProcs,
2675 fileObj[0]);
2676 }
2677 if (!ins_rc[1] && fileObj[1]) {
2678 PyDict_DelItem(_PyPopenProcs,
2679 fileObj[1]);
2680 }
2681 if (!ins_rc[2] && fileObj[2]) {
2682 PyDict_DelItem(_PyPopenProcs,
2683 fileObj[2]);
2684 }
2685 }
2686 }
2687
2688 /*
2689 * Clean up our localized references for the dictionary keys
2690 * and value since PyDict_SetItem will Py_INCREF any copies
2691 * that got placed in the dictionary.
2692 */
2693 Py_XDECREF(procObj);
2694 Py_XDECREF(fileObj[0]);
2695 Py_XDECREF(fileObj[1]);
2696 Py_XDECREF(fileObj[2]);
2697 }
2698
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002699 /* Child is launched. Close the parents copy of those pipe
2700 * handles that only the child should have open. You need to
2701 * make sure that no handles to the write end of the output pipe
2702 * are maintained in this process or else the pipe will not close
2703 * when the child process exits and the ReadFile will hang. */
2704
2705 if (!CloseHandle(hChildStdinRd))
2706 return win32_error("CloseHandle", NULL);
2707
2708 if (!CloseHandle(hChildStdoutWr))
2709 return win32_error("CloseHandle", NULL);
2710
2711 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2712 return win32_error("CloseHandle", NULL);
2713
2714 return f;
2715}
Fredrik Lundh56055a42000-07-23 19:47:12 +00002716
2717/*
2718 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2719 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00002720 *
2721 * This function uses the _PyPopenProcs dictionary in order to map the
2722 * input file pointer to information about the process that was
2723 * originally created by the popen* call that created the file pointer.
2724 * The dictionary uses the file pointer as a key (with one entry
2725 * inserted for each file returned by the original popen* call) and a
2726 * single list object as the value for all files from a single call.
2727 * The list object contains the Win32 process handle at [0], and a file
2728 * count at [1], which is initialized to the total number of file
2729 * handles using that list.
2730 *
2731 * This function closes whichever handle it is passed, and decrements
2732 * the file count in the dictionary for the process handle pointed to
2733 * by this file. On the last close (when the file count reaches zero),
2734 * this function will wait for the child process and then return its
2735 * exit code as the result of the close() operation. This permits the
2736 * files to be closed in any order - it is always the close() of the
2737 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002738 */
Tim Peters736aa322000-09-01 06:51:24 +00002739
2740 /* RED_FLAG 31-Aug-2000 Tim
2741 * This is always called (today!) between a pair of
2742 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2743 * macros. So the thread running this has no valid thread state, as
2744 * far as Python is concerned. However, this calls some Python API
2745 * functions that cannot be called safely without a valid thread
2746 * state, in particular PyDict_GetItem.
2747 * As a temporary hack (although it may last for years ...), we
2748 * *rely* on not having a valid thread state in this function, in
2749 * order to create our own "from scratch".
2750 * This will deadlock if _PyPclose is ever called by a thread
2751 * holding the global lock.
2752 */
2753
Fredrik Lundh56055a42000-07-23 19:47:12 +00002754static int _PyPclose(FILE *file)
2755{
Fredrik Lundh20318932000-07-26 17:29:12 +00002756 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002757 DWORD exit_code;
2758 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00002759 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
2760 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00002761#ifdef WITH_THREAD
2762 PyInterpreterState* pInterpreterState;
2763 PyThreadState* pThreadState;
2764#endif
2765
Fredrik Lundh20318932000-07-26 17:29:12 +00002766 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00002767 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00002768 */
2769 result = fclose(file);
2770
Tim Peters736aa322000-09-01 06:51:24 +00002771#ifdef WITH_THREAD
2772 /* Bootstrap a valid thread state into existence. */
2773 pInterpreterState = PyInterpreterState_New();
2774 if (!pInterpreterState) {
2775 /* Well, we're hosed now! We don't have a thread
2776 * state, so can't call a nice error routine, or raise
2777 * an exception. Just die.
2778 */
2779 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00002780 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00002781 return -1; /* unreachable */
2782 }
2783 pThreadState = PyThreadState_New(pInterpreterState);
2784 if (!pThreadState) {
2785 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00002786 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00002787 return -1; /* unreachable */
2788 }
2789 /* Grab the global lock. Note that this will deadlock if the
2790 * current thread already has the lock! (see RED_FLAG comments
2791 * before this function)
2792 */
2793 PyEval_RestoreThread(pThreadState);
2794#endif
2795
Fredrik Lundh56055a42000-07-23 19:47:12 +00002796 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00002797 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2798 (procObj = PyDict_GetItem(_PyPopenProcs,
2799 fileObj)) != NULL &&
2800 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
2801 (intObj = PyList_GetItem(procObj,1)) != NULL) {
2802
2803 hProcess = PyLong_AsVoidPtr(hProcessObj);
2804 file_count = PyInt_AsLong(intObj);
2805
2806 if (file_count > 1) {
2807 /* Still other files referencing process */
2808 file_count--;
2809 PyList_SetItem(procObj,1,
2810 PyInt_FromLong(file_count));
2811 } else {
2812 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00002813 if (result != EOF &&
2814 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
2815 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00002816 /* Possible truncation here in 16-bit environments, but
2817 * real exit codes are just the lower byte in any event.
2818 */
2819 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002820 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00002821 /* Indicate failure - this will cause the file object
2822 * to raise an I/O error and translate the last Win32
2823 * error code from errno. We do have a problem with
2824 * last errors that overlap the normal errno table,
2825 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002826 */
Fredrik Lundh20318932000-07-26 17:29:12 +00002827 if (result != EOF) {
2828 /* If the error wasn't from the fclose(), then
2829 * set errno for the file object error handling.
2830 */
2831 errno = GetLastError();
2832 }
2833 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002834 }
2835
2836 /* Free up the native handle at this point */
2837 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00002838 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00002839
Mark Hammondb37a3732000-08-14 04:47:33 +00002840 /* Remove this file pointer from dictionary */
2841 PyDict_DelItem(_PyPopenProcs, fileObj);
2842
2843 if (PyDict_Size(_PyPopenProcs) == 0) {
2844 Py_DECREF(_PyPopenProcs);
2845 _PyPopenProcs = NULL;
2846 }
2847
2848 } /* if object retrieval ok */
2849
2850 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002851 } /* if _PyPopenProcs */
2852
Tim Peters736aa322000-09-01 06:51:24 +00002853#ifdef WITH_THREAD
2854 /* Tear down the thread & interpreter states.
2855 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00002856 * call the thread clear & delete functions, and indeed insist on
2857 * doing that themselves. The lock must be held during the clear, but
2858 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00002859 */
2860 PyInterpreterState_Clear(pInterpreterState);
2861 PyEval_ReleaseThread(pThreadState);
2862 PyInterpreterState_Delete(pInterpreterState);
2863#endif
2864
Fredrik Lundh56055a42000-07-23 19:47:12 +00002865 return result;
2866}
Tim Peters9acdd3a2000-09-01 19:26:36 +00002867
2868#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00002869static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002870posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00002871{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002872 char *name;
2873 char *mode = "r";
2874 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00002875 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00002876 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002877 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00002878 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002879 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002880 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00002881 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00002882 if (fp == NULL)
2883 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002884 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002885 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00002886 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002887 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00002888}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002889#endif
2890
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002891#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00002892
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002893
Guido van Rossumb6775db1994-08-01 11:34:53 +00002894#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002895static char posix_setuid__doc__[] =
2896"setuid(uid) -> None\n\
2897Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00002898static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002899posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002900{
2901 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002902 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002903 return NULL;
2904 if (setuid(uid) < 0)
2905 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002906 Py_INCREF(Py_None);
2907 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002908}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002909#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002910
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002911
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00002912#ifdef HAVE_SETEUID
2913static char posix_seteuid__doc__[] =
2914"seteuid(uid) -> None\n\
2915Set the current process's effective user id.";
2916static PyObject *
2917posix_seteuid (PyObject *self, PyObject *args)
2918{
2919 int euid;
2920 if (!PyArg_ParseTuple(args, "i", &euid)) {
2921 return NULL;
2922 } else if (seteuid(euid) < 0) {
2923 return posix_error();
2924 } else {
2925 Py_INCREF(Py_None);
2926 return Py_None;
2927 }
2928}
2929#endif /* HAVE_SETEUID */
2930
2931#ifdef HAVE_SETEGID
2932static char posix_setegid__doc__[] =
2933"setegid(gid) -> None\n\
2934Set the current process's effective group id.";
2935static PyObject *
2936posix_setegid (PyObject *self, PyObject *args)
2937{
2938 int egid;
2939 if (!PyArg_ParseTuple(args, "i", &egid)) {
2940 return NULL;
2941 } else if (setegid(egid) < 0) {
2942 return posix_error();
2943 } else {
2944 Py_INCREF(Py_None);
2945 return Py_None;
2946 }
2947}
2948#endif /* HAVE_SETEGID */
2949
2950#ifdef HAVE_SETREUID
2951static char posix_setreuid__doc__[] =
2952"seteuid(ruid, euid) -> None\n\
2953Set the current process's real and effective user ids.";
2954static PyObject *
2955posix_setreuid (PyObject *self, PyObject *args)
2956{
2957 int ruid, euid;
2958 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
2959 return NULL;
2960 } else if (setreuid(ruid, euid) < 0) {
2961 return posix_error();
2962 } else {
2963 Py_INCREF(Py_None);
2964 return Py_None;
2965 }
2966}
2967#endif /* HAVE_SETREUID */
2968
2969#ifdef HAVE_SETREGID
2970static char posix_setregid__doc__[] =
2971"setegid(rgid, egid) -> None\n\
2972Set the current process's real and effective group ids.";
2973static PyObject *
2974posix_setregid (PyObject *self, PyObject *args)
2975{
2976 int rgid, egid;
2977 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
2978 return NULL;
2979 } else if (setregid(rgid, egid) < 0) {
2980 return posix_error();
2981 } else {
2982 Py_INCREF(Py_None);
2983 return Py_None;
2984 }
2985}
2986#endif /* HAVE_SETREGID */
2987
Guido van Rossumb6775db1994-08-01 11:34:53 +00002988#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002989static char posix_setgid__doc__[] =
2990"setgid(gid) -> None\n\
2991Set the current process's group id.";
2992
Barry Warsaw53699e91996-12-10 23:23:01 +00002993static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002994posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002995{
2996 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002997 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002998 return NULL;
2999 if (setgid(gid) < 0)
3000 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003001 Py_INCREF(Py_None);
3002 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003003}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003004#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003005
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003006
Guido van Rossumb6775db1994-08-01 11:34:53 +00003007#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003008static char posix_waitpid__doc__[] =
3009"waitpid(pid, options) -> (pid, status)\n\
Guido van Rossumf377d572000-12-12 00:37:58 +00003010Wait for completion of a given child process.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003011
Barry Warsaw53699e91996-12-10 23:23:01 +00003012static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003013posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003014{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003015 int pid, options;
3016#ifdef UNION_WAIT
3017 union wait status;
3018#define status_i (status.w_status)
3019#else
3020 int status;
3021#define status_i status
3022#endif
3023 status_i = 0;
3024
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003025 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00003026 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003027 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003028#ifdef NeXT
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003029 pid = wait4(pid, &status, options, NULL);
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003030#else
3031 pid = waitpid(pid, &status, options);
3032#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003033 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00003034 if (pid == -1)
3035 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00003036 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003037 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00003038}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003039#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +00003040
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003041
Guido van Rossumad0ee831995-03-01 10:34:45 +00003042#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003043static char posix_wait__doc__[] =
3044"wait() -> (pid, status)\n\
3045Wait for completion of a child process.";
3046
Barry Warsaw53699e91996-12-10 23:23:01 +00003047static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003048posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00003049{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003050 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003051#ifdef UNION_WAIT
3052 union wait status;
3053#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003054#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003055 int status;
3056#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003057#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003058 if (!PyArg_ParseTuple(args, ":wait"))
3059 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003060 status_i = 0;
3061 Py_BEGIN_ALLOW_THREADS
3062 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00003063 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00003064 if (pid == -1)
3065 return posix_error();
3066 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003067 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003068#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00003069}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003070#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003071
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003072
3073static char posix_lstat__doc__[] =
3074"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
3075Like stat(path), but do not follow symbolic links.";
3076
Barry Warsaw53699e91996-12-10 23:23:01 +00003077static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003078posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003079{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003080#ifdef HAVE_LSTAT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003081 return posix_do_stat(self, args, "s:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003082#else /* !HAVE_LSTAT */
Fred Drake699f3522000-06-29 21:12:41 +00003083 return posix_do_stat(self, args, "s:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003084#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003085}
3086
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003087
Guido van Rossumb6775db1994-08-01 11:34:53 +00003088#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003089static char posix_readlink__doc__[] =
3090"readlink(path) -> path\n\
3091Return a string representing the path to which the symbolic link points.";
3092
Barry Warsaw53699e91996-12-10 23:23:01 +00003093static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003094posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003095{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003096 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003097 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003098 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003099 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003100 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003101 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00003102 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00003103 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003104 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003105 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00003106 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003107}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003108#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003109
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003110
Guido van Rossumb6775db1994-08-01 11:34:53 +00003111#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003112static char posix_symlink__doc__[] =
3113"symlink(src, dst) -> None\n\
3114Create a symbolic link.";
3115
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003116static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003117posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003118{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003119 return posix_2str(args, "ss:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003120}
3121#endif /* HAVE_SYMLINK */
3122
3123
3124#ifdef HAVE_TIMES
3125#ifndef HZ
3126#define HZ 60 /* Universal constant :-) */
3127#endif /* HZ */
3128
Guido van Rossumd48f2521997-12-05 22:19:34 +00003129#if defined(PYCC_VACPP) && defined(PYOS_OS2)
3130static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003131system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003132{
3133 ULONG value = 0;
3134
3135 Py_BEGIN_ALLOW_THREADS
3136 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
3137 Py_END_ALLOW_THREADS
3138
3139 return value;
3140}
3141
3142static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003143posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003144{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003145 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00003146 return NULL;
3147
3148 /* Currently Only Uptime is Provided -- Others Later */
3149 return Py_BuildValue("ddddd",
3150 (double)0 /* t.tms_utime / HZ */,
3151 (double)0 /* t.tms_stime / HZ */,
3152 (double)0 /* t.tms_cutime / HZ */,
3153 (double)0 /* t.tms_cstime / HZ */,
3154 (double)system_uptime() / 1000);
3155}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003156#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003157static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003158posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00003159{
3160 struct tms t;
3161 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003162 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00003163 return NULL;
3164 errno = 0;
3165 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00003166 if (c == (clock_t) -1)
3167 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003168 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00003169 (double)t.tms_utime / HZ,
3170 (double)t.tms_stime / HZ,
3171 (double)t.tms_cutime / HZ,
3172 (double)t.tms_cstime / HZ,
3173 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00003174}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003175#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003176#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003177
3178
Guido van Rossum87755a21996-09-07 00:59:43 +00003179#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003180#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00003181static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003182posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003183{
3184 FILETIME create, exit, kernel, user;
3185 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003186 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003187 return NULL;
3188 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003189 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
3190 /* The fields of a FILETIME structure are the hi and lo part
3191 of a 64-bit value expressed in 100 nanosecond units.
3192 1e7 is one second in such units; 1e-7 the inverse.
3193 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
3194 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003195 return Py_BuildValue(
3196 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003197 (double)(kernel.dwHighDateTime*429.4967296 +
3198 kernel.dwLowDateTime*1e-7),
3199 (double)(user.dwHighDateTime*429.4967296 +
3200 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00003201 (double)0,
3202 (double)0,
3203 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003204}
Guido van Rossum8d665e61996-06-26 18:22:49 +00003205#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003206
3207#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00003208static char posix_times__doc__[] =
3209"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
3210Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003211#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003212
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003213
Guido van Rossumb6775db1994-08-01 11:34:53 +00003214#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003215static char posix_setsid__doc__[] =
3216"setsid() -> None\n\
3217Call the system call setsid().";
3218
Barry Warsaw53699e91996-12-10 23:23:01 +00003219static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003220posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003221{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003222 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003223 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003224 if (setsid() < 0)
3225 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003226 Py_INCREF(Py_None);
3227 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003228}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003229#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003230
Guido van Rossumb6775db1994-08-01 11:34:53 +00003231#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003232static char posix_setpgid__doc__[] =
3233"setpgid(pid, pgrp) -> None\n\
3234Call the system call setpgid().";
3235
Barry Warsaw53699e91996-12-10 23:23:01 +00003236static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003237posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003238{
3239 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003240 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003241 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003242 if (setpgid(pid, pgrp) < 0)
3243 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003244 Py_INCREF(Py_None);
3245 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003246}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003247#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003248
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003249
Guido van Rossumb6775db1994-08-01 11:34:53 +00003250#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003251static char posix_tcgetpgrp__doc__[] =
3252"tcgetpgrp(fd) -> pgid\n\
3253Return the process group associated with the terminal given by a fd.";
3254
Barry Warsaw53699e91996-12-10 23:23:01 +00003255static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003256posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003257{
3258 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003259 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003260 return NULL;
3261 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003262 if (pgid < 0)
3263 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003264 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00003265}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003266#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00003267
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003268
Guido van Rossumb6775db1994-08-01 11:34:53 +00003269#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003270static char posix_tcsetpgrp__doc__[] =
3271"tcsetpgrp(fd, pgid) -> None\n\
3272Set the process group associated with the terminal given by a fd.";
3273
Barry Warsaw53699e91996-12-10 23:23:01 +00003274static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003275posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003276{
3277 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003278 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003279 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003280 if (tcsetpgrp(fd, pgid) < 0)
3281 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00003282 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00003283 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00003284}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003285#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00003286
Guido van Rossum687dd131993-05-17 08:34:16 +00003287/* Functions acting on file descriptors */
3288
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003289static char posix_open__doc__[] =
3290"open(filename, flag [, mode=0777]) -> fd\n\
3291Open a file (for low level IO).";
3292
Barry Warsaw53699e91996-12-10 23:23:01 +00003293static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003294posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003295{
3296 char *file;
3297 int flag;
3298 int mode = 0777;
3299 int fd;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003300 if (!PyArg_ParseTuple(args, "si|i", &file, &flag, &mode))
3301 return NULL;
3302
Barry Warsaw53699e91996-12-10 23:23:01 +00003303 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003304 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003305 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003306 if (fd < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003307 return posix_error_with_filename(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00003308 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003309}
3310
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003311
3312static char posix_close__doc__[] =
3313"close(fd) -> None\n\
3314Close a file descriptor (for low level IO).";
3315
Barry Warsaw53699e91996-12-10 23:23:01 +00003316static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003317posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003318{
3319 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003320 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003321 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003322 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003323 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003324 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003325 if (res < 0)
3326 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003327 Py_INCREF(Py_None);
3328 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003329}
3330
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003331
3332static char posix_dup__doc__[] =
3333"dup(fd) -> fd2\n\
3334Return a duplicate of a file descriptor.";
3335
Barry Warsaw53699e91996-12-10 23:23:01 +00003336static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003337posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003338{
3339 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003340 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003341 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003342 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003343 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003344 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003345 if (fd < 0)
3346 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003347 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003348}
3349
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003350
3351static char posix_dup2__doc__[] =
3352"dup2(fd, fd2) -> None\n\
3353Duplicate file descriptor.";
3354
Barry Warsaw53699e91996-12-10 23:23:01 +00003355static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003356posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003357{
3358 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003359 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00003360 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003361 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003362 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00003363 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003364 if (res < 0)
3365 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003366 Py_INCREF(Py_None);
3367 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003368}
3369
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003370
3371static char posix_lseek__doc__[] =
3372"lseek(fd, pos, how) -> newpos\n\
3373Set the current position of a file descriptor.";
3374
Barry Warsaw53699e91996-12-10 23:23:01 +00003375static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003376posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003377{
3378 int fd, how;
Fred Drake699f3522000-06-29 21:12:41 +00003379#ifdef MS_WIN64
3380 LONG_LONG pos, res;
3381#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003382 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003383#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003384 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003385 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003386 return NULL;
3387#ifdef SEEK_SET
3388 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3389 switch (how) {
3390 case 0: how = SEEK_SET; break;
3391 case 1: how = SEEK_CUR; break;
3392 case 2: how = SEEK_END; break;
3393 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003394#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003395
3396#if !defined(HAVE_LARGEFILE_SUPPORT)
3397 pos = PyInt_AsLong(posobj);
3398#else
3399 pos = PyLong_Check(posobj) ?
3400 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3401#endif
3402 if (PyErr_Occurred())
3403 return NULL;
3404
Barry Warsaw53699e91996-12-10 23:23:01 +00003405 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003406#ifdef MS_WIN64
3407 res = _lseeki64(fd, pos, how);
3408#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003409 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003410#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003411 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003412 if (res < 0)
3413 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003414
3415#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003416 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003417#else
3418 return PyLong_FromLongLong(res);
3419#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003420}
3421
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003422
3423static char posix_read__doc__[] =
3424"read(fd, buffersize) -> string\n\
3425Read a file descriptor.";
3426
Barry Warsaw53699e91996-12-10 23:23:01 +00003427static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003428posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003429{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003430 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003431 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003432 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003433 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003434 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003435 if (buffer == NULL)
3436 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003437 Py_BEGIN_ALLOW_THREADS
3438 n = read(fd, PyString_AsString(buffer), size);
3439 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003440 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003441 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003442 return posix_error();
3443 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003444 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003445 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003446 return buffer;
3447}
3448
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003449
3450static char posix_write__doc__[] =
3451"write(fd, string) -> byteswritten\n\
3452Write a string to a file descriptor.";
3453
Barry Warsaw53699e91996-12-10 23:23:01 +00003454static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003455posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003456{
3457 int fd, size;
3458 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003459 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003460 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003461 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003462 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003463 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003464 if (size < 0)
3465 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003466 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003467}
3468
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003469
3470static char posix_fstat__doc__[]=
3471"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3472Like stat(), but for an open file descriptor.";
3473
Barry Warsaw53699e91996-12-10 23:23:01 +00003474static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003475posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003476{
3477 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003478 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003479 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003480 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003481 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003482 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003483 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003484 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003485 if (res != 0)
3486 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00003487
3488 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003489}
3490
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003491
3492static char posix_fdopen__doc__[] =
3493"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3494Return an open file object connected to a file descriptor.";
3495
Barry Warsaw53699e91996-12-10 23:23:01 +00003496static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003497posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003498{
Guido van Rossum687dd131993-05-17 08:34:16 +00003499 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003500 char *mode = "r";
3501 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003502 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003503 PyObject *f;
3504 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003505 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003506
Barry Warsaw53699e91996-12-10 23:23:01 +00003507 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003508 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003509 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003510 if (fp == NULL)
3511 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003512 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003513 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003514 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003515 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003516}
3517
Skip Montanaro1517d842000-07-19 14:34:14 +00003518static char posix_isatty__doc__[] =
3519"isatty(fd) -> Boolean\n\
3520Return true if the file descriptor 'fd' is an open file descriptor\n\
Thomas Wouters12e15952000-10-03 16:54:24 +00003521connected to the slave end of a terminal.";
Skip Montanaro1517d842000-07-19 14:34:14 +00003522
3523static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00003524posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00003525{
3526 int fd;
3527 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3528 return NULL;
3529 return Py_BuildValue("i", isatty(fd));
3530}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003531
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003532#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003533static char posix_pipe__doc__[] =
3534"pipe() -> (read_end, write_end)\n\
3535Create a pipe.";
3536
Barry Warsaw53699e91996-12-10 23:23:01 +00003537static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003538posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003539{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003540#if defined(PYOS_OS2)
3541 HFILE read, write;
3542 APIRET rc;
3543
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003544 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003545 return NULL;
3546
3547 Py_BEGIN_ALLOW_THREADS
3548 rc = DosCreatePipe( &read, &write, 4096);
3549 Py_END_ALLOW_THREADS
3550 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003551 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003552
3553 return Py_BuildValue("(ii)", read, write);
3554#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003555#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003556 int fds[2];
3557 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003558 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003559 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003560 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003561 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003562 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003563 if (res != 0)
3564 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003565 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003566#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003567 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003568 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003569 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003570 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003571 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003572 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003573 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003574 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003575 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003576 return win32_error("CreatePipe", NULL);
Fred Drake699f3522000-06-29 21:12:41 +00003577 read_fd = _open_osfhandle((intptr_t)read, 0);
3578 write_fd = _open_osfhandle((intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003579 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003580#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003581#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003582}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003583#endif /* HAVE_PIPE */
3584
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003585
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003586#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003587static char posix_mkfifo__doc__[] =
3588"mkfifo(file, [, mode=0666]) -> None\n\
3589Create a FIFO (a POSIX named pipe).";
3590
Barry Warsaw53699e91996-12-10 23:23:01 +00003591static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003592posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003593{
3594 char *file;
3595 int mode = 0666;
3596 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003597 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003598 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003599 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003600 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003601 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003602 if (res < 0)
3603 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003604 Py_INCREF(Py_None);
3605 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003606}
3607#endif
3608
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003609
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003610#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003611static char posix_ftruncate__doc__[] =
3612"ftruncate(fd, length) -> None\n\
3613Truncate a file to a specified length.";
3614
Barry Warsaw53699e91996-12-10 23:23:01 +00003615static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003616posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003617{
3618 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003619 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003620 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003621 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003622
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003623 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003624 return NULL;
3625
3626#if !defined(HAVE_LARGEFILE_SUPPORT)
3627 length = PyInt_AsLong(lenobj);
3628#else
3629 length = PyLong_Check(lenobj) ?
3630 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3631#endif
3632 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003633 return NULL;
3634
Barry Warsaw53699e91996-12-10 23:23:01 +00003635 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003636 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003637 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003638 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003639 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003640 return NULL;
3641 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003642 Py_INCREF(Py_None);
3643 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003644}
3645#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003646
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003647#ifdef NeXT
3648#define HAVE_PUTENV
3649/* Steve Spicklemire got this putenv from NeXTAnswers */
3650static int
3651putenv(char *newval)
3652{
3653 extern char **environ;
3654
3655 static int firstTime = 1;
3656 char **ep;
3657 char *cp;
3658 int esiz;
3659 char *np;
3660
3661 if (!(np = strchr(newval, '=')))
3662 return 1;
3663 *np = '\0';
3664
3665 /* look it up */
3666 for (ep=environ ; *ep ; ep++)
3667 {
3668 /* this should always be true... */
3669 if (cp = strchr(*ep, '='))
3670 {
3671 *cp = '\0';
3672 if (!strcmp(*ep, newval))
3673 {
3674 /* got it! */
3675 *cp = '=';
3676 break;
3677 }
3678 *cp = '=';
3679 }
3680 else
3681 {
3682 *np = '=';
3683 return 1;
3684 }
3685 }
3686
3687 *np = '=';
3688 if (*ep)
3689 {
3690 /* the string was already there:
3691 just replace it with the new one */
3692 *ep = newval;
3693 return 0;
3694 }
3695
3696 /* expand environ by one */
3697 for (esiz=2, ep=environ ; *ep ; ep++)
3698 esiz++;
3699 if (firstTime)
3700 {
3701 char **epp;
3702 char **newenv;
3703 if (!(newenv = malloc(esiz * sizeof(char *))))
3704 return 1;
3705
3706 for (ep=environ, epp=newenv ; *ep ;)
3707 *epp++ = *ep++;
3708 *epp++ = newval;
3709 *epp = (char *) 0;
3710 environ = newenv;
3711 }
3712 else
3713 {
3714 if (!(environ = realloc(environ, esiz * sizeof(char *))))
3715 return 1;
3716 environ[esiz - 2] = newval;
3717 environ[esiz - 1] = (char *) 0;
3718 firstTime = 0;
3719 }
3720
3721 return 0;
3722}
Guido van Rossumc6ef2041997-08-21 02:30:45 +00003723#endif /* NeXT */
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003724
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003725
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003726#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003727static char posix_putenv__doc__[] =
3728"putenv(key, value) -> None\n\
3729Change or add an environment variable.";
3730
Fred Drake762e2061999-08-26 17:23:54 +00003731/* Save putenv() parameters as values here, so we can collect them when they
3732 * get re-set with another call for the same key. */
3733static PyObject *posix_putenv_garbage;
3734
Barry Warsaw53699e91996-12-10 23:23:01 +00003735static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003736posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003737{
3738 char *s1, *s2;
3739 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00003740 PyObject *newstr;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003741
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003742 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003743 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003744
3745#if defined(PYOS_OS2)
3746 if (stricmp(s1, "BEGINLIBPATH") == 0) {
3747 APIRET rc;
3748
3749 if (strlen(s2) == 0) /* If New Value is an Empty String */
3750 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3751
3752 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
3753 if (rc != NO_ERROR)
3754 return os2_error(rc);
3755
3756 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
3757 APIRET rc;
3758
3759 if (strlen(s2) == 0) /* If New Value is an Empty String */
3760 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3761
3762 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
3763 if (rc != NO_ERROR)
3764 return os2_error(rc);
3765 } else {
3766#endif
3767
Fred Drake762e2061999-08-26 17:23:54 +00003768 /* XXX This can leak memory -- not easy to fix :-( */
3769 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
3770 if (newstr == NULL)
3771 return PyErr_NoMemory();
3772 new = PyString_AS_STRING(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003773 (void) sprintf(new, "%s=%s", s1, s2);
3774 if (putenv(new)) {
3775 posix_error();
3776 return NULL;
3777 }
Fred Drake762e2061999-08-26 17:23:54 +00003778 /* Install the first arg and newstr in posix_putenv_garbage;
3779 * this will cause previous value to be collected. This has to
3780 * happen after the real putenv() call because the old value
3781 * was still accessible until then. */
3782 if (PyDict_SetItem(posix_putenv_garbage,
3783 PyTuple_GET_ITEM(args, 0), newstr)) {
3784 /* really not much we can do; just leak */
3785 PyErr_Clear();
3786 }
3787 else {
3788 Py_DECREF(newstr);
3789 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003790
3791#if defined(PYOS_OS2)
3792 }
3793#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003794 Py_INCREF(Py_None);
3795 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003796}
Guido van Rossumb6a47161997-09-15 22:54:34 +00003797#endif /* putenv */
3798
3799#ifdef HAVE_STRERROR
3800static char posix_strerror__doc__[] =
3801"strerror(code) -> string\n\
3802Translate an error code to a message string.";
3803
3804PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003805posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00003806{
3807 int code;
3808 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003809 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00003810 return NULL;
3811 message = strerror(code);
3812 if (message == NULL) {
3813 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00003814 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00003815 return NULL;
3816 }
3817 return PyString_FromString(message);
3818}
3819#endif /* strerror */
3820
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003821
Guido van Rossumc9641791998-08-04 15:26:23 +00003822#ifdef HAVE_SYS_WAIT_H
3823
3824#ifdef WIFSTOPPED
3825static char posix_WIFSTOPPED__doc__[] =
3826"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003827Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003828
3829static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003830posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003831{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003832#ifdef UNION_WAIT
3833 union wait status;
3834#define status_i (status.w_status)
3835#else
3836 int status;
3837#define status_i status
3838#endif
3839 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003840
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003841 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003842 {
3843 return NULL;
3844 }
3845
3846 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003847#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003848}
3849#endif /* WIFSTOPPED */
3850
3851#ifdef WIFSIGNALED
3852static char posix_WIFSIGNALED__doc__[] =
3853"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00003854Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003855
3856static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003857posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003858{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003859#ifdef UNION_WAIT
3860 union wait status;
3861#define status_i (status.w_status)
3862#else
3863 int status;
3864#define status_i status
3865#endif
3866 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003867
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003868 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003869 {
3870 return NULL;
3871 }
3872
3873 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003874#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003875}
3876#endif /* WIFSIGNALED */
3877
3878#ifdef WIFEXITED
3879static char posix_WIFEXITED__doc__[] =
3880"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003881Return true if the process returning 'status' exited using the exit()\n\
3882system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003883
3884static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003885posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003886{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003887#ifdef UNION_WAIT
3888 union wait status;
3889#define status_i (status.w_status)
3890#else
3891 int status;
3892#define status_i status
3893#endif
3894 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003895
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003896 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003897 {
3898 return NULL;
3899 }
3900
3901 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003902#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003903}
3904#endif /* WIFEXITED */
3905
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003906#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00003907static char posix_WEXITSTATUS__doc__[] =
3908"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003909Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003910
3911static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003912posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003913{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003914#ifdef UNION_WAIT
3915 union wait status;
3916#define status_i (status.w_status)
3917#else
3918 int status;
3919#define status_i status
3920#endif
3921 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003922
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003923 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003924 {
3925 return NULL;
3926 }
3927
3928 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003929#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003930}
3931#endif /* WEXITSTATUS */
3932
3933#ifdef WTERMSIG
3934static char posix_WTERMSIG__doc__[] =
3935"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003936Return the signal that terminated the process that provided the 'status'\n\
3937value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003938
3939static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003940posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003941{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003942#ifdef UNION_WAIT
3943 union wait status;
3944#define status_i (status.w_status)
3945#else
3946 int status;
3947#define status_i status
3948#endif
3949 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003950
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003951 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003952 {
3953 return NULL;
3954 }
3955
3956 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003957#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003958}
3959#endif /* WTERMSIG */
3960
3961#ifdef WSTOPSIG
3962static char posix_WSTOPSIG__doc__[] =
3963"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003964Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003965
3966static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003967posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003968{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003969#ifdef UNION_WAIT
3970 union wait status;
3971#define status_i (status.w_status)
3972#else
3973 int status;
3974#define status_i status
3975#endif
3976 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003977
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003978 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003979 {
3980 return NULL;
3981 }
3982
3983 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003984#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003985}
3986#endif /* WSTOPSIG */
3987
3988#endif /* HAVE_SYS_WAIT_H */
3989
3990
Guido van Rossum94f6f721999-01-06 18:42:14 +00003991#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00003992#ifdef _SCO_DS
3993/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
3994 needed definitions in sys/statvfs.h */
3995#define _SVID3
3996#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003997#include <sys/statvfs.h>
3998
3999static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004000"fstatvfs(fd) -> \n\
4001 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004002Perform an fstatvfs system call on the given fd.";
4003
4004static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004005posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004006{
4007 int fd, res;
4008 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004009 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004010 return NULL;
4011 Py_BEGIN_ALLOW_THREADS
4012 res = fstatvfs(fd, &st);
4013 Py_END_ALLOW_THREADS
4014 if (res != 0)
4015 return posix_error();
4016#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004017 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004018 (long) st.f_bsize,
4019 (long) st.f_frsize,
4020 (long) st.f_blocks,
4021 (long) st.f_bfree,
4022 (long) st.f_bavail,
4023 (long) st.f_files,
4024 (long) st.f_ffree,
4025 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004026 (long) st.f_flag,
4027 (long) st.f_namemax);
4028#else
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004029 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004030 (long) st.f_bsize,
4031 (long) st.f_frsize,
4032 (LONG_LONG) st.f_blocks,
4033 (LONG_LONG) st.f_bfree,
4034 (LONG_LONG) st.f_bavail,
4035 (LONG_LONG) st.f_files,
4036 (LONG_LONG) st.f_ffree,
4037 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004038 (long) st.f_flag,
4039 (long) st.f_namemax);
4040#endif
4041}
4042#endif /* HAVE_FSTATVFS */
4043
4044
4045#if defined(HAVE_STATVFS)
4046#include <sys/statvfs.h>
4047
4048static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004049"statvfs(path) -> \n\
4050 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004051Perform a statvfs system call on the given path.";
4052
4053static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004054posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004055{
4056 char *path;
4057 int res;
4058 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004059 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004060 return NULL;
4061 Py_BEGIN_ALLOW_THREADS
4062 res = statvfs(path, &st);
4063 Py_END_ALLOW_THREADS
4064 if (res != 0)
4065 return posix_error_with_filename(path);
4066#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004067 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004068 (long) st.f_bsize,
4069 (long) st.f_frsize,
4070 (long) st.f_blocks,
4071 (long) st.f_bfree,
4072 (long) st.f_bavail,
4073 (long) st.f_files,
4074 (long) st.f_ffree,
4075 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004076 (long) st.f_flag,
4077 (long) st.f_namemax);
4078#else /* HAVE_LARGEFILE_SUPPORT */
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004079 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004080 (long) st.f_bsize,
4081 (long) st.f_frsize,
4082 (LONG_LONG) st.f_blocks,
4083 (LONG_LONG) st.f_bfree,
4084 (LONG_LONG) st.f_bavail,
4085 (LONG_LONG) st.f_files,
4086 (LONG_LONG) st.f_ffree,
4087 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004088 (long) st.f_flag,
4089 (long) st.f_namemax);
4090#endif
4091}
4092#endif /* HAVE_STATVFS */
4093
4094
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004095#ifdef HAVE_TEMPNAM
4096static char posix_tempnam__doc__[] = "\
4097tempnam([dir[, prefix]]) -> string\n\
4098Return a unique name for a temporary file.\n\
4099The directory and a short may be specified as strings; they may be omitted\n\
4100or None if not needed.";
4101
4102static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004103posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004104{
4105 PyObject *result = NULL;
4106 char *dir = NULL;
4107 char *pfx = NULL;
4108 char *name;
4109
4110 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
4111 return NULL;
4112 name = tempnam(dir, pfx);
4113 if (name == NULL)
4114 return PyErr_NoMemory();
4115 result = PyString_FromString(name);
4116 free(name);
4117 return result;
4118}
Guido van Rossumd371ff11999-01-25 16:12:23 +00004119#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004120
4121
4122#ifdef HAVE_TMPFILE
4123static char posix_tmpfile__doc__[] = "\
4124tmpfile() -> file object\n\
4125Create a temporary file with no directory entries.";
4126
4127static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004128posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004129{
4130 FILE *fp;
4131
4132 if (!PyArg_ParseTuple(args, ":tmpfile"))
4133 return NULL;
4134 fp = tmpfile();
4135 if (fp == NULL)
4136 return posix_error();
4137 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
4138}
4139#endif
4140
4141
4142#ifdef HAVE_TMPNAM
4143static char posix_tmpnam__doc__[] = "\
4144tmpnam() -> string\n\
4145Return a unique name for a temporary file.";
4146
4147static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004148posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004149{
4150 char buffer[L_tmpnam];
4151 char *name;
4152
4153 if (!PyArg_ParseTuple(args, ":tmpnam"))
4154 return NULL;
Greg Wardb48bc172000-03-01 21:51:56 +00004155#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004156 name = tmpnam_r(buffer);
4157#else
4158 name = tmpnam(buffer);
4159#endif
4160 if (name == NULL) {
4161 PyErr_SetObject(PyExc_OSError,
4162 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00004163#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004164 "unexpected NULL from tmpnam_r"
4165#else
4166 "unexpected NULL from tmpnam"
4167#endif
4168 ));
4169 return NULL;
4170 }
4171 return PyString_FromString(buffer);
4172}
4173#endif
4174
4175
Fred Drakec9680921999-12-13 16:37:25 +00004176/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
4177 * It maps strings representing configuration variable names to
4178 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00004179 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00004180 * rarely-used constants. There are three separate tables that use
4181 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00004182 *
4183 * This code is always included, even if none of the interfaces that
4184 * need it are included. The #if hackery needed to avoid it would be
4185 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00004186 */
4187struct constdef {
4188 char *name;
4189 long value;
4190};
4191
Fred Drake12c6e2d1999-12-14 21:25:03 +00004192static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004193conv_confname(PyObject *arg, int *valuep, struct constdef *table,
4194 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004195{
4196 if (PyInt_Check(arg)) {
4197 *valuep = PyInt_AS_LONG(arg);
4198 return 1;
4199 }
4200 if (PyString_Check(arg)) {
4201 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00004202 size_t lo = 0;
4203 size_t mid;
4204 size_t hi = tablesize;
4205 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004206 char *confname = PyString_AS_STRING(arg);
4207 while (lo < hi) {
4208 mid = (lo + hi) / 2;
4209 cmp = strcmp(confname, table[mid].name);
4210 if (cmp < 0)
4211 hi = mid;
4212 else if (cmp > 0)
4213 lo = mid + 1;
4214 else {
4215 *valuep = table[mid].value;
4216 return 1;
4217 }
4218 }
4219 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
4220 }
4221 else
4222 PyErr_SetString(PyExc_TypeError,
4223 "configuration names must be strings or integers");
4224 return 0;
4225}
4226
4227
4228#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4229static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004230#ifdef _PC_ABI_AIO_XFER_MAX
4231 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
4232#endif
4233#ifdef _PC_ABI_ASYNC_IO
4234 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
4235#endif
Fred Drakec9680921999-12-13 16:37:25 +00004236#ifdef _PC_ASYNC_IO
4237 {"PC_ASYNC_IO", _PC_ASYNC_IO},
4238#endif
4239#ifdef _PC_CHOWN_RESTRICTED
4240 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
4241#endif
4242#ifdef _PC_FILESIZEBITS
4243 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
4244#endif
4245#ifdef _PC_LAST
4246 {"PC_LAST", _PC_LAST},
4247#endif
4248#ifdef _PC_LINK_MAX
4249 {"PC_LINK_MAX", _PC_LINK_MAX},
4250#endif
4251#ifdef _PC_MAX_CANON
4252 {"PC_MAX_CANON", _PC_MAX_CANON},
4253#endif
4254#ifdef _PC_MAX_INPUT
4255 {"PC_MAX_INPUT", _PC_MAX_INPUT},
4256#endif
4257#ifdef _PC_NAME_MAX
4258 {"PC_NAME_MAX", _PC_NAME_MAX},
4259#endif
4260#ifdef _PC_NO_TRUNC
4261 {"PC_NO_TRUNC", _PC_NO_TRUNC},
4262#endif
4263#ifdef _PC_PATH_MAX
4264 {"PC_PATH_MAX", _PC_PATH_MAX},
4265#endif
4266#ifdef _PC_PIPE_BUF
4267 {"PC_PIPE_BUF", _PC_PIPE_BUF},
4268#endif
4269#ifdef _PC_PRIO_IO
4270 {"PC_PRIO_IO", _PC_PRIO_IO},
4271#endif
4272#ifdef _PC_SOCK_MAXBUF
4273 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
4274#endif
4275#ifdef _PC_SYNC_IO
4276 {"PC_SYNC_IO", _PC_SYNC_IO},
4277#endif
4278#ifdef _PC_VDISABLE
4279 {"PC_VDISABLE", _PC_VDISABLE},
4280#endif
4281};
4282
Fred Drakec9680921999-12-13 16:37:25 +00004283static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004284conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004285{
4286 return conv_confname(arg, valuep, posix_constants_pathconf,
4287 sizeof(posix_constants_pathconf)
4288 / sizeof(struct constdef));
4289}
4290#endif
4291
4292#ifdef HAVE_FPATHCONF
4293static char posix_fpathconf__doc__[] = "\
4294fpathconf(fd, name) -> integer\n\
4295Return the configuration limit name for the file descriptor fd.\n\
4296If there is no limit, return -1.";
4297
4298static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004299posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004300{
4301 PyObject *result = NULL;
4302 int name, fd;
4303
Fred Drake12c6e2d1999-12-14 21:25:03 +00004304 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4305 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00004306 long limit;
4307
4308 errno = 0;
4309 limit = fpathconf(fd, name);
4310 if (limit == -1 && errno != 0)
4311 posix_error();
4312 else
4313 result = PyInt_FromLong(limit);
4314 }
4315 return result;
4316}
4317#endif
4318
4319
4320#ifdef HAVE_PATHCONF
4321static char posix_pathconf__doc__[] = "\
4322pathconf(path, name) -> integer\n\
4323Return the configuration limit name for the file or directory path.\n\
4324If there is no limit, return -1.";
4325
4326static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004327posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004328{
4329 PyObject *result = NULL;
4330 int name;
4331 char *path;
4332
4333 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4334 conv_path_confname, &name)) {
4335 long limit;
4336
4337 errno = 0;
4338 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004339 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00004340 if (errno == EINVAL)
4341 /* could be a path or name problem */
4342 posix_error();
4343 else
4344 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004345 }
Fred Drakec9680921999-12-13 16:37:25 +00004346 else
4347 result = PyInt_FromLong(limit);
4348 }
4349 return result;
4350}
4351#endif
4352
4353#ifdef HAVE_CONFSTR
4354static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004355#ifdef _CS_ARCHITECTURE
4356 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4357#endif
4358#ifdef _CS_HOSTNAME
4359 {"CS_HOSTNAME", _CS_HOSTNAME},
4360#endif
4361#ifdef _CS_HW_PROVIDER
4362 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4363#endif
4364#ifdef _CS_HW_SERIAL
4365 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4366#endif
4367#ifdef _CS_INITTAB_NAME
4368 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4369#endif
Fred Drakec9680921999-12-13 16:37:25 +00004370#ifdef _CS_LFS64_CFLAGS
4371 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4372#endif
4373#ifdef _CS_LFS64_LDFLAGS
4374 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4375#endif
4376#ifdef _CS_LFS64_LIBS
4377 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4378#endif
4379#ifdef _CS_LFS64_LINTFLAGS
4380 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4381#endif
4382#ifdef _CS_LFS_CFLAGS
4383 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4384#endif
4385#ifdef _CS_LFS_LDFLAGS
4386 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4387#endif
4388#ifdef _CS_LFS_LIBS
4389 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4390#endif
4391#ifdef _CS_LFS_LINTFLAGS
4392 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4393#endif
Fred Draked86ed291999-12-15 15:34:33 +00004394#ifdef _CS_MACHINE
4395 {"CS_MACHINE", _CS_MACHINE},
4396#endif
Fred Drakec9680921999-12-13 16:37:25 +00004397#ifdef _CS_PATH
4398 {"CS_PATH", _CS_PATH},
4399#endif
Fred Draked86ed291999-12-15 15:34:33 +00004400#ifdef _CS_RELEASE
4401 {"CS_RELEASE", _CS_RELEASE},
4402#endif
4403#ifdef _CS_SRPC_DOMAIN
4404 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4405#endif
4406#ifdef _CS_SYSNAME
4407 {"CS_SYSNAME", _CS_SYSNAME},
4408#endif
4409#ifdef _CS_VERSION
4410 {"CS_VERSION", _CS_VERSION},
4411#endif
Fred Drakec9680921999-12-13 16:37:25 +00004412#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4413 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4414#endif
4415#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4416 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4417#endif
4418#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4419 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4420#endif
4421#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4422 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4423#endif
4424#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4425 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4426#endif
4427#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4428 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4429#endif
4430#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4431 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4432#endif
4433#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4434 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4435#endif
4436#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4437 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4438#endif
4439#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4440 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4441#endif
4442#ifdef _CS_XBS5_LP64_OFF64_LIBS
4443 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4444#endif
4445#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4446 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4447#endif
4448#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4449 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4450#endif
4451#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4452 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4453#endif
4454#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4455 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4456#endif
4457#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4458 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4459#endif
Fred Draked86ed291999-12-15 15:34:33 +00004460#ifdef _MIPS_CS_AVAIL_PROCESSORS
4461 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4462#endif
4463#ifdef _MIPS_CS_BASE
4464 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4465#endif
4466#ifdef _MIPS_CS_HOSTID
4467 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4468#endif
4469#ifdef _MIPS_CS_HW_NAME
4470 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4471#endif
4472#ifdef _MIPS_CS_NUM_PROCESSORS
4473 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4474#endif
4475#ifdef _MIPS_CS_OSREL_MAJ
4476 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4477#endif
4478#ifdef _MIPS_CS_OSREL_MIN
4479 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4480#endif
4481#ifdef _MIPS_CS_OSREL_PATCH
4482 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4483#endif
4484#ifdef _MIPS_CS_OS_NAME
4485 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4486#endif
4487#ifdef _MIPS_CS_OS_PROVIDER
4488 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4489#endif
4490#ifdef _MIPS_CS_PROCESSORS
4491 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4492#endif
4493#ifdef _MIPS_CS_SERIAL
4494 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4495#endif
4496#ifdef _MIPS_CS_VENDOR
4497 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4498#endif
Fred Drakec9680921999-12-13 16:37:25 +00004499};
4500
4501static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004502conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004503{
4504 return conv_confname(arg, valuep, posix_constants_confstr,
4505 sizeof(posix_constants_confstr)
4506 / sizeof(struct constdef));
4507}
4508
4509static char posix_confstr__doc__[] = "\
4510confstr(name) -> string\n\
4511Return a string-valued system configuration variable.";
4512
4513static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004514posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004515{
4516 PyObject *result = NULL;
4517 int name;
4518 char buffer[64];
4519
4520 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4521 int len = confstr(name, buffer, sizeof(buffer));
4522
Fred Drakec9680921999-12-13 16:37:25 +00004523 errno = 0;
4524 if (len == 0) {
4525 if (errno != 0)
4526 posix_error();
4527 else
4528 result = PyString_FromString("");
4529 }
4530 else {
4531 if (len >= sizeof(buffer)) {
4532 result = PyString_FromStringAndSize(NULL, len);
4533 if (result != NULL)
4534 confstr(name, PyString_AS_STRING(result), len+1);
4535 }
4536 else
4537 result = PyString_FromString(buffer);
4538 }
4539 }
4540 return result;
4541}
4542#endif
4543
4544
4545#ifdef HAVE_SYSCONF
4546static struct constdef posix_constants_sysconf[] = {
4547#ifdef _SC_2_CHAR_TERM
4548 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4549#endif
4550#ifdef _SC_2_C_BIND
4551 {"SC_2_C_BIND", _SC_2_C_BIND},
4552#endif
4553#ifdef _SC_2_C_DEV
4554 {"SC_2_C_DEV", _SC_2_C_DEV},
4555#endif
4556#ifdef _SC_2_C_VERSION
4557 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4558#endif
4559#ifdef _SC_2_FORT_DEV
4560 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4561#endif
4562#ifdef _SC_2_FORT_RUN
4563 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4564#endif
4565#ifdef _SC_2_LOCALEDEF
4566 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4567#endif
4568#ifdef _SC_2_SW_DEV
4569 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4570#endif
4571#ifdef _SC_2_UPE
4572 {"SC_2_UPE", _SC_2_UPE},
4573#endif
4574#ifdef _SC_2_VERSION
4575 {"SC_2_VERSION", _SC_2_VERSION},
4576#endif
Fred Draked86ed291999-12-15 15:34:33 +00004577#ifdef _SC_ABI_ASYNCHRONOUS_IO
4578 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4579#endif
4580#ifdef _SC_ACL
4581 {"SC_ACL", _SC_ACL},
4582#endif
Fred Drakec9680921999-12-13 16:37:25 +00004583#ifdef _SC_AIO_LISTIO_MAX
4584 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4585#endif
Fred Drakec9680921999-12-13 16:37:25 +00004586#ifdef _SC_AIO_MAX
4587 {"SC_AIO_MAX", _SC_AIO_MAX},
4588#endif
4589#ifdef _SC_AIO_PRIO_DELTA_MAX
4590 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4591#endif
4592#ifdef _SC_ARG_MAX
4593 {"SC_ARG_MAX", _SC_ARG_MAX},
4594#endif
4595#ifdef _SC_ASYNCHRONOUS_IO
4596 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4597#endif
4598#ifdef _SC_ATEXIT_MAX
4599 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4600#endif
Fred Draked86ed291999-12-15 15:34:33 +00004601#ifdef _SC_AUDIT
4602 {"SC_AUDIT", _SC_AUDIT},
4603#endif
Fred Drakec9680921999-12-13 16:37:25 +00004604#ifdef _SC_AVPHYS_PAGES
4605 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4606#endif
4607#ifdef _SC_BC_BASE_MAX
4608 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4609#endif
4610#ifdef _SC_BC_DIM_MAX
4611 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4612#endif
4613#ifdef _SC_BC_SCALE_MAX
4614 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4615#endif
4616#ifdef _SC_BC_STRING_MAX
4617 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4618#endif
Fred Draked86ed291999-12-15 15:34:33 +00004619#ifdef _SC_CAP
4620 {"SC_CAP", _SC_CAP},
4621#endif
Fred Drakec9680921999-12-13 16:37:25 +00004622#ifdef _SC_CHARCLASS_NAME_MAX
4623 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4624#endif
4625#ifdef _SC_CHAR_BIT
4626 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4627#endif
4628#ifdef _SC_CHAR_MAX
4629 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4630#endif
4631#ifdef _SC_CHAR_MIN
4632 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4633#endif
4634#ifdef _SC_CHILD_MAX
4635 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4636#endif
4637#ifdef _SC_CLK_TCK
4638 {"SC_CLK_TCK", _SC_CLK_TCK},
4639#endif
4640#ifdef _SC_COHER_BLKSZ
4641 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4642#endif
4643#ifdef _SC_COLL_WEIGHTS_MAX
4644 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4645#endif
4646#ifdef _SC_DCACHE_ASSOC
4647 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4648#endif
4649#ifdef _SC_DCACHE_BLKSZ
4650 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4651#endif
4652#ifdef _SC_DCACHE_LINESZ
4653 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4654#endif
4655#ifdef _SC_DCACHE_SZ
4656 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
4657#endif
4658#ifdef _SC_DCACHE_TBLKSZ
4659 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
4660#endif
4661#ifdef _SC_DELAYTIMER_MAX
4662 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
4663#endif
4664#ifdef _SC_EQUIV_CLASS_MAX
4665 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
4666#endif
4667#ifdef _SC_EXPR_NEST_MAX
4668 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
4669#endif
4670#ifdef _SC_FSYNC
4671 {"SC_FSYNC", _SC_FSYNC},
4672#endif
4673#ifdef _SC_GETGR_R_SIZE_MAX
4674 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
4675#endif
4676#ifdef _SC_GETPW_R_SIZE_MAX
4677 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
4678#endif
4679#ifdef _SC_ICACHE_ASSOC
4680 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
4681#endif
4682#ifdef _SC_ICACHE_BLKSZ
4683 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
4684#endif
4685#ifdef _SC_ICACHE_LINESZ
4686 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
4687#endif
4688#ifdef _SC_ICACHE_SZ
4689 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
4690#endif
Fred Draked86ed291999-12-15 15:34:33 +00004691#ifdef _SC_INF
4692 {"SC_INF", _SC_INF},
4693#endif
Fred Drakec9680921999-12-13 16:37:25 +00004694#ifdef _SC_INT_MAX
4695 {"SC_INT_MAX", _SC_INT_MAX},
4696#endif
4697#ifdef _SC_INT_MIN
4698 {"SC_INT_MIN", _SC_INT_MIN},
4699#endif
4700#ifdef _SC_IOV_MAX
4701 {"SC_IOV_MAX", _SC_IOV_MAX},
4702#endif
Fred Draked86ed291999-12-15 15:34:33 +00004703#ifdef _SC_IP_SECOPTS
4704 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
4705#endif
Fred Drakec9680921999-12-13 16:37:25 +00004706#ifdef _SC_JOB_CONTROL
4707 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
4708#endif
Fred Draked86ed291999-12-15 15:34:33 +00004709#ifdef _SC_KERN_POINTERS
4710 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
4711#endif
4712#ifdef _SC_KERN_SIM
4713 {"SC_KERN_SIM", _SC_KERN_SIM},
4714#endif
Fred Drakec9680921999-12-13 16:37:25 +00004715#ifdef _SC_LINE_MAX
4716 {"SC_LINE_MAX", _SC_LINE_MAX},
4717#endif
4718#ifdef _SC_LOGIN_NAME_MAX
4719 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
4720#endif
4721#ifdef _SC_LOGNAME_MAX
4722 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
4723#endif
4724#ifdef _SC_LONG_BIT
4725 {"SC_LONG_BIT", _SC_LONG_BIT},
4726#endif
Fred Draked86ed291999-12-15 15:34:33 +00004727#ifdef _SC_MAC
4728 {"SC_MAC", _SC_MAC},
4729#endif
Fred Drakec9680921999-12-13 16:37:25 +00004730#ifdef _SC_MAPPED_FILES
4731 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
4732#endif
4733#ifdef _SC_MAXPID
4734 {"SC_MAXPID", _SC_MAXPID},
4735#endif
4736#ifdef _SC_MB_LEN_MAX
4737 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
4738#endif
4739#ifdef _SC_MEMLOCK
4740 {"SC_MEMLOCK", _SC_MEMLOCK},
4741#endif
4742#ifdef _SC_MEMLOCK_RANGE
4743 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
4744#endif
4745#ifdef _SC_MEMORY_PROTECTION
4746 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
4747#endif
4748#ifdef _SC_MESSAGE_PASSING
4749 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
4750#endif
Fred Draked86ed291999-12-15 15:34:33 +00004751#ifdef _SC_MMAP_FIXED_ALIGNMENT
4752 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
4753#endif
Fred Drakec9680921999-12-13 16:37:25 +00004754#ifdef _SC_MQ_OPEN_MAX
4755 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
4756#endif
4757#ifdef _SC_MQ_PRIO_MAX
4758 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
4759#endif
Fred Draked86ed291999-12-15 15:34:33 +00004760#ifdef _SC_NACLS_MAX
4761 {"SC_NACLS_MAX", _SC_NACLS_MAX},
4762#endif
Fred Drakec9680921999-12-13 16:37:25 +00004763#ifdef _SC_NGROUPS_MAX
4764 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
4765#endif
4766#ifdef _SC_NL_ARGMAX
4767 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
4768#endif
4769#ifdef _SC_NL_LANGMAX
4770 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
4771#endif
4772#ifdef _SC_NL_MSGMAX
4773 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
4774#endif
4775#ifdef _SC_NL_NMAX
4776 {"SC_NL_NMAX", _SC_NL_NMAX},
4777#endif
4778#ifdef _SC_NL_SETMAX
4779 {"SC_NL_SETMAX", _SC_NL_SETMAX},
4780#endif
4781#ifdef _SC_NL_TEXTMAX
4782 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
4783#endif
4784#ifdef _SC_NPROCESSORS_CONF
4785 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
4786#endif
4787#ifdef _SC_NPROCESSORS_ONLN
4788 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
4789#endif
Fred Draked86ed291999-12-15 15:34:33 +00004790#ifdef _SC_NPROC_CONF
4791 {"SC_NPROC_CONF", _SC_NPROC_CONF},
4792#endif
4793#ifdef _SC_NPROC_ONLN
4794 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
4795#endif
Fred Drakec9680921999-12-13 16:37:25 +00004796#ifdef _SC_NZERO
4797 {"SC_NZERO", _SC_NZERO},
4798#endif
4799#ifdef _SC_OPEN_MAX
4800 {"SC_OPEN_MAX", _SC_OPEN_MAX},
4801#endif
4802#ifdef _SC_PAGESIZE
4803 {"SC_PAGESIZE", _SC_PAGESIZE},
4804#endif
4805#ifdef _SC_PAGE_SIZE
4806 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
4807#endif
4808#ifdef _SC_PASS_MAX
4809 {"SC_PASS_MAX", _SC_PASS_MAX},
4810#endif
4811#ifdef _SC_PHYS_PAGES
4812 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
4813#endif
4814#ifdef _SC_PII
4815 {"SC_PII", _SC_PII},
4816#endif
4817#ifdef _SC_PII_INTERNET
4818 {"SC_PII_INTERNET", _SC_PII_INTERNET},
4819#endif
4820#ifdef _SC_PII_INTERNET_DGRAM
4821 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
4822#endif
4823#ifdef _SC_PII_INTERNET_STREAM
4824 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
4825#endif
4826#ifdef _SC_PII_OSI
4827 {"SC_PII_OSI", _SC_PII_OSI},
4828#endif
4829#ifdef _SC_PII_OSI_CLTS
4830 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
4831#endif
4832#ifdef _SC_PII_OSI_COTS
4833 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
4834#endif
4835#ifdef _SC_PII_OSI_M
4836 {"SC_PII_OSI_M", _SC_PII_OSI_M},
4837#endif
4838#ifdef _SC_PII_SOCKET
4839 {"SC_PII_SOCKET", _SC_PII_SOCKET},
4840#endif
4841#ifdef _SC_PII_XTI
4842 {"SC_PII_XTI", _SC_PII_XTI},
4843#endif
4844#ifdef _SC_POLL
4845 {"SC_POLL", _SC_POLL},
4846#endif
4847#ifdef _SC_PRIORITIZED_IO
4848 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
4849#endif
4850#ifdef _SC_PRIORITY_SCHEDULING
4851 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
4852#endif
4853#ifdef _SC_REALTIME_SIGNALS
4854 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
4855#endif
4856#ifdef _SC_RE_DUP_MAX
4857 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
4858#endif
4859#ifdef _SC_RTSIG_MAX
4860 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
4861#endif
4862#ifdef _SC_SAVED_IDS
4863 {"SC_SAVED_IDS", _SC_SAVED_IDS},
4864#endif
4865#ifdef _SC_SCHAR_MAX
4866 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
4867#endif
4868#ifdef _SC_SCHAR_MIN
4869 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
4870#endif
4871#ifdef _SC_SELECT
4872 {"SC_SELECT", _SC_SELECT},
4873#endif
4874#ifdef _SC_SEMAPHORES
4875 {"SC_SEMAPHORES", _SC_SEMAPHORES},
4876#endif
4877#ifdef _SC_SEM_NSEMS_MAX
4878 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
4879#endif
4880#ifdef _SC_SEM_VALUE_MAX
4881 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
4882#endif
4883#ifdef _SC_SHARED_MEMORY_OBJECTS
4884 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
4885#endif
4886#ifdef _SC_SHRT_MAX
4887 {"SC_SHRT_MAX", _SC_SHRT_MAX},
4888#endif
4889#ifdef _SC_SHRT_MIN
4890 {"SC_SHRT_MIN", _SC_SHRT_MIN},
4891#endif
4892#ifdef _SC_SIGQUEUE_MAX
4893 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
4894#endif
4895#ifdef _SC_SIGRT_MAX
4896 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
4897#endif
4898#ifdef _SC_SIGRT_MIN
4899 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
4900#endif
Fred Draked86ed291999-12-15 15:34:33 +00004901#ifdef _SC_SOFTPOWER
4902 {"SC_SOFTPOWER", _SC_SOFTPOWER},
4903#endif
Fred Drakec9680921999-12-13 16:37:25 +00004904#ifdef _SC_SPLIT_CACHE
4905 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
4906#endif
4907#ifdef _SC_SSIZE_MAX
4908 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
4909#endif
4910#ifdef _SC_STACK_PROT
4911 {"SC_STACK_PROT", _SC_STACK_PROT},
4912#endif
4913#ifdef _SC_STREAM_MAX
4914 {"SC_STREAM_MAX", _SC_STREAM_MAX},
4915#endif
4916#ifdef _SC_SYNCHRONIZED_IO
4917 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
4918#endif
4919#ifdef _SC_THREADS
4920 {"SC_THREADS", _SC_THREADS},
4921#endif
4922#ifdef _SC_THREAD_ATTR_STACKADDR
4923 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
4924#endif
4925#ifdef _SC_THREAD_ATTR_STACKSIZE
4926 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
4927#endif
4928#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
4929 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
4930#endif
4931#ifdef _SC_THREAD_KEYS_MAX
4932 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
4933#endif
4934#ifdef _SC_THREAD_PRIORITY_SCHEDULING
4935 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
4936#endif
4937#ifdef _SC_THREAD_PRIO_INHERIT
4938 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
4939#endif
4940#ifdef _SC_THREAD_PRIO_PROTECT
4941 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
4942#endif
4943#ifdef _SC_THREAD_PROCESS_SHARED
4944 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
4945#endif
4946#ifdef _SC_THREAD_SAFE_FUNCTIONS
4947 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
4948#endif
4949#ifdef _SC_THREAD_STACK_MIN
4950 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
4951#endif
4952#ifdef _SC_THREAD_THREADS_MAX
4953 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
4954#endif
4955#ifdef _SC_TIMERS
4956 {"SC_TIMERS", _SC_TIMERS},
4957#endif
4958#ifdef _SC_TIMER_MAX
4959 {"SC_TIMER_MAX", _SC_TIMER_MAX},
4960#endif
4961#ifdef _SC_TTY_NAME_MAX
4962 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
4963#endif
4964#ifdef _SC_TZNAME_MAX
4965 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
4966#endif
4967#ifdef _SC_T_IOV_MAX
4968 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
4969#endif
4970#ifdef _SC_UCHAR_MAX
4971 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
4972#endif
4973#ifdef _SC_UINT_MAX
4974 {"SC_UINT_MAX", _SC_UINT_MAX},
4975#endif
4976#ifdef _SC_UIO_MAXIOV
4977 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
4978#endif
4979#ifdef _SC_ULONG_MAX
4980 {"SC_ULONG_MAX", _SC_ULONG_MAX},
4981#endif
4982#ifdef _SC_USHRT_MAX
4983 {"SC_USHRT_MAX", _SC_USHRT_MAX},
4984#endif
4985#ifdef _SC_VERSION
4986 {"SC_VERSION", _SC_VERSION},
4987#endif
4988#ifdef _SC_WORD_BIT
4989 {"SC_WORD_BIT", _SC_WORD_BIT},
4990#endif
4991#ifdef _SC_XBS5_ILP32_OFF32
4992 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
4993#endif
4994#ifdef _SC_XBS5_ILP32_OFFBIG
4995 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
4996#endif
4997#ifdef _SC_XBS5_LP64_OFF64
4998 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
4999#endif
5000#ifdef _SC_XBS5_LPBIG_OFFBIG
5001 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
5002#endif
5003#ifdef _SC_XOPEN_CRYPT
5004 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
5005#endif
5006#ifdef _SC_XOPEN_ENH_I18N
5007 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
5008#endif
5009#ifdef _SC_XOPEN_LEGACY
5010 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
5011#endif
5012#ifdef _SC_XOPEN_REALTIME
5013 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
5014#endif
5015#ifdef _SC_XOPEN_REALTIME_THREADS
5016 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
5017#endif
5018#ifdef _SC_XOPEN_SHM
5019 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
5020#endif
5021#ifdef _SC_XOPEN_UNIX
5022 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
5023#endif
5024#ifdef _SC_XOPEN_VERSION
5025 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
5026#endif
5027#ifdef _SC_XOPEN_XCU_VERSION
5028 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
5029#endif
5030#ifdef _SC_XOPEN_XPG2
5031 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
5032#endif
5033#ifdef _SC_XOPEN_XPG3
5034 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
5035#endif
5036#ifdef _SC_XOPEN_XPG4
5037 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
5038#endif
5039};
5040
5041static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005042conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005043{
5044 return conv_confname(arg, valuep, posix_constants_sysconf,
5045 sizeof(posix_constants_sysconf)
5046 / sizeof(struct constdef));
5047}
5048
5049static char posix_sysconf__doc__[] = "\
5050sysconf(name) -> integer\n\
5051Return an integer-valued system configuration variable.";
5052
5053static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005054posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005055{
5056 PyObject *result = NULL;
5057 int name;
5058
5059 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
5060 int value;
5061
5062 errno = 0;
5063 value = sysconf(name);
5064 if (value == -1 && errno != 0)
5065 posix_error();
5066 else
5067 result = PyInt_FromLong(value);
5068 }
5069 return result;
5070}
5071#endif
5072
5073
Fred Drakebec628d1999-12-15 18:31:10 +00005074/* This code is used to ensure that the tables of configuration value names
5075 * are in sorted order as required by conv_confname(), and also to build the
5076 * the exported dictionaries that are used to publish information about the
5077 * names available on the host platform.
5078 *
5079 * Sorting the table at runtime ensures that the table is properly ordered
5080 * when used, even for platforms we're not able to test on. It also makes
5081 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00005082 */
Fred Drakebec628d1999-12-15 18:31:10 +00005083
5084static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005085cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00005086{
5087 const struct constdef *c1 =
5088 (const struct constdef *) v1;
5089 const struct constdef *c2 =
5090 (const struct constdef *) v2;
5091
5092 return strcmp(c1->name, c2->name);
5093}
5094
5095static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005096setup_confname_table(struct constdef *table, size_t tablesize,
5097 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005098{
Fred Drakebec628d1999-12-15 18:31:10 +00005099 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00005100 size_t i;
5101 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00005102
5103 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
5104 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00005105 if (d == NULL)
5106 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005107
Barry Warsaw3155db32000-04-13 15:20:40 +00005108 for (i=0; i < tablesize; ++i) {
5109 PyObject *o = PyInt_FromLong(table[i].value);
5110 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
5111 Py_XDECREF(o);
5112 Py_DECREF(d);
5113 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005114 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005115 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00005116 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005117 status = PyDict_SetItemString(moddict, tablename, d);
5118 Py_DECREF(d);
5119 return status;
Fred Draked86ed291999-12-15 15:34:33 +00005120}
5121
Fred Drakebec628d1999-12-15 18:31:10 +00005122/* Return -1 on failure, 0 on success. */
5123static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005124setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005125{
5126#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00005127 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00005128 sizeof(posix_constants_pathconf)
5129 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005130 "pathconf_names", moddict))
5131 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005132#endif
5133#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00005134 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00005135 sizeof(posix_constants_confstr)
5136 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005137 "confstr_names", moddict))
5138 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005139#endif
5140#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00005141 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00005142 sizeof(posix_constants_sysconf)
5143 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005144 "sysconf_names", moddict))
5145 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005146#endif
Fred Drakebec628d1999-12-15 18:31:10 +00005147 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00005148}
Fred Draked86ed291999-12-15 15:34:33 +00005149
5150
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005151static char posix_abort__doc__[] = "\
5152abort() -> does not return!\n\
5153Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
5154in the hardest way possible on the hosting operating system.";
5155
5156static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005157posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005158{
5159 if (!PyArg_ParseTuple(args, ":abort"))
5160 return NULL;
5161 abort();
5162 /*NOTREACHED*/
5163 Py_FatalError("abort() called from Python code didn't abort!");
5164 return NULL;
5165}
Fred Drakebec628d1999-12-15 18:31:10 +00005166
Tim Petersf58a7aa2000-09-22 10:05:54 +00005167#ifdef MS_WIN32
5168static char win32_startfile__doc__[] = "\
5169startfile(filepath) - Start a file with its associated application.\n\
5170\n\
5171This acts like double-clicking the file in Explorer, or giving the file\n\
5172name as an argument to the DOS \"start\" command: the file is opened\n\
5173with whatever application (if any) its extension is associated.\n\
5174\n\
5175startfile returns as soon as the associated application is launched.\n\
5176There is no option to wait for the application to close, and no way\n\
5177to retrieve the application's exit status.\n\
5178\n\
5179The filepath is relative to the current directory. If you want to use\n\
5180an absolute path, make sure the first character is not a slash (\"/\");\n\
5181the underlying Win32 ShellExecute function doesn't work if it is.";
5182
5183static PyObject *
5184win32_startfile(PyObject *self, PyObject *args)
5185{
5186 char *filepath;
5187 HINSTANCE rc;
5188 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
5189 return NULL;
5190 Py_BEGIN_ALLOW_THREADS
5191 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
5192 Py_END_ALLOW_THREADS
5193 if (rc <= (HINSTANCE)32)
5194 return win32_error("startfile", filepath);
5195 Py_INCREF(Py_None);
5196 return Py_None;
5197}
5198#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005199
5200static PyMethodDef posix_methods[] = {
5201 {"access", posix_access, METH_VARARGS, posix_access__doc__},
5202#ifdef HAVE_TTYNAME
5203 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
5204#endif
5205 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
5206 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005207#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005208 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005209#endif /* HAVE_CHOWN */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005210#ifdef HAVE_CTERMID
5211 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
5212#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00005213#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005214 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00005215#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005216#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005217 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005218#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005219 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
5220 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
5221 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005222#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005223 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005224#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005225#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005226 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005227#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005228 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
5229 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
5230 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005231#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005232 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005233#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005234#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005235 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005236#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005237 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005238#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005239 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005240#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005241 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
5242 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
5243 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005244#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005245 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005246#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005247 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005248#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005249 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5250 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005251#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00005252#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005253 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5254 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00005255#endif /* HAVE_SPAWNV */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005256#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005257 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005258#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005259#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005260 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00005261#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005262#ifdef HAVE_FORKPTY
5263 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5264#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005265#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005266 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005267#endif /* HAVE_GETEGID */
5268#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005269 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005270#endif /* HAVE_GETEUID */
5271#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005272 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005273#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00005274#ifdef HAVE_GETGROUPS
5275 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5276#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005277 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005278#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005279 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005280#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005281#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005282 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005283#endif /* HAVE_GETPPID */
5284#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005285 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005286#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005287#ifdef HAVE_GETLOGIN
5288 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5289#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00005290#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005291 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005292#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00005293#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005294 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00005295#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005296#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005297 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005298#ifdef MS_WIN32
5299 {"popen2", win32_popen2, METH_VARARGS},
5300 {"popen3", win32_popen3, METH_VARARGS},
5301 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00005302 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005303#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005304#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005305#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005306 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005307#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005308#ifdef HAVE_SETEUID
5309 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5310#endif /* HAVE_SETEUID */
5311#ifdef HAVE_SETEGID
5312 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5313#endif /* HAVE_SETEGID */
5314#ifdef HAVE_SETREUID
5315 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5316#endif /* HAVE_SETREUID */
5317#ifdef HAVE_SETREGID
5318 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5319#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005320#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005321 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005322#endif /* HAVE_SETGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005323#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005324 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005325#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005326#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005327 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005328#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005329#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005330 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005331#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005332#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005333 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005334#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005335#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005336 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005337#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005338#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005339 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005340#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005341#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005342 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005343#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005344 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5345 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5346 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5347 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5348 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5349 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5350 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5351 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5352 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00005353 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005354#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005355 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005356#endif
5357#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005358 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005359#endif
5360#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005361 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005362#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005363#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005364 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005365#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00005366#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005367 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00005368#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00005369#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005370 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005371#endif
5372#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005373 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005374#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00005375#ifdef HAVE_SYS_WAIT_H
5376#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005377 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005378#endif /* WIFSTOPPED */
5379#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005380 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005381#endif /* WIFSIGNALED */
5382#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005383 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005384#endif /* WIFEXITED */
5385#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005386 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005387#endif /* WEXITSTATUS */
5388#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005389 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005390#endif /* WTERMSIG */
5391#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005392 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005393#endif /* WSTOPSIG */
5394#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005395#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005396 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005397#endif
5398#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005399 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005400#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00005401#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005402 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5403#endif
5404#ifdef HAVE_TEMPNAM
5405 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5406#endif
5407#ifdef HAVE_TMPNAM
5408 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5409#endif
Fred Drakec9680921999-12-13 16:37:25 +00005410#ifdef HAVE_CONFSTR
5411 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5412#endif
5413#ifdef HAVE_SYSCONF
5414 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5415#endif
5416#ifdef HAVE_FPATHCONF
5417 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5418#endif
5419#ifdef HAVE_PATHCONF
5420 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5421#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005422 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005423 {NULL, NULL} /* Sentinel */
5424};
5425
5426
Barry Warsaw4a342091996-12-19 23:50:02 +00005427static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005428ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005429{
5430 PyObject* v = PyInt_FromLong(value);
5431 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5432 return -1; /* triggers fatal error */
5433
5434 Py_DECREF(v);
5435 return 0;
5436}
5437
Guido van Rossumd48f2521997-12-05 22:19:34 +00005438#if defined(PYOS_OS2)
5439/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5440static int insertvalues(PyObject *d)
5441{
5442 APIRET rc;
5443 ULONG values[QSV_MAX+1];
5444 PyObject *v;
5445 char *ver, tmp[10];
5446
5447 Py_BEGIN_ALLOW_THREADS
5448 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5449 Py_END_ALLOW_THREADS
5450
5451 if (rc != NO_ERROR) {
5452 os2_error(rc);
5453 return -1;
5454 }
5455
5456 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5457 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5458 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5459 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5460 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5461 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5462 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5463
5464 switch (values[QSV_VERSION_MINOR]) {
5465 case 0: ver = "2.00"; break;
5466 case 10: ver = "2.10"; break;
5467 case 11: ver = "2.11"; break;
5468 case 30: ver = "3.00"; break;
5469 case 40: ver = "4.00"; break;
5470 case 50: ver = "5.00"; break;
5471 default:
5472 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
5473 values[QSV_VERSION_MINOR]);
5474 ver = &tmp[0];
5475 }
5476
5477 /* Add Indicator of the Version of the Operating System */
5478 v = PyString_FromString(ver);
5479 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5480 return -1;
5481 Py_DECREF(v);
5482
5483 /* Add Indicator of Which Drive was Used to Boot the System */
5484 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5485 tmp[1] = ':';
5486 tmp[2] = '\0';
5487
5488 v = PyString_FromString(tmp);
5489 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5490 return -1;
5491 Py_DECREF(v);
5492
5493 return 0;
5494}
5495#endif
5496
Barry Warsaw4a342091996-12-19 23:50:02 +00005497static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005498all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00005499{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005500#ifdef F_OK
5501 if (ins(d, "F_OK", (long)F_OK)) return -1;
5502#endif
5503#ifdef R_OK
5504 if (ins(d, "R_OK", (long)R_OK)) return -1;
5505#endif
5506#ifdef W_OK
5507 if (ins(d, "W_OK", (long)W_OK)) return -1;
5508#endif
5509#ifdef X_OK
5510 if (ins(d, "X_OK", (long)X_OK)) return -1;
5511#endif
Fred Drakec9680921999-12-13 16:37:25 +00005512#ifdef NGROUPS_MAX
5513 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5514#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005515#ifdef TMP_MAX
5516 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5517#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005518#ifdef WNOHANG
5519 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5520#endif
5521#ifdef O_RDONLY
5522 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5523#endif
5524#ifdef O_WRONLY
5525 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5526#endif
5527#ifdef O_RDWR
5528 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5529#endif
5530#ifdef O_NDELAY
5531 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5532#endif
5533#ifdef O_NONBLOCK
5534 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5535#endif
5536#ifdef O_APPEND
5537 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5538#endif
5539#ifdef O_DSYNC
5540 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5541#endif
5542#ifdef O_RSYNC
5543 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5544#endif
5545#ifdef O_SYNC
5546 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5547#endif
5548#ifdef O_NOCTTY
5549 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5550#endif
5551#ifdef O_CREAT
5552 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5553#endif
5554#ifdef O_EXCL
5555 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5556#endif
5557#ifdef O_TRUNC
5558 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5559#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005560#ifdef O_BINARY
5561 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5562#endif
5563#ifdef O_TEXT
5564 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5565#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005566
Guido van Rossum246bc171999-02-01 23:54:31 +00005567#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005568 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5569 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5570 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5571 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5572 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005573#endif
5574
Guido van Rossumd48f2521997-12-05 22:19:34 +00005575#if defined(PYOS_OS2)
5576 if (insertvalues(d)) return -1;
5577#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005578 return 0;
5579}
5580
5581
Guido van Rossumc5a0f531997-12-02 20:36:02 +00005582#if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005583#define INITFUNC initnt
5584#define MODNAME "nt"
5585#else
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005586#if defined(PYOS_OS2)
5587#define INITFUNC initos2
5588#define MODNAME "os2"
5589#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005590#define INITFUNC initposix
5591#define MODNAME "posix"
5592#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005593#endif
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005594
Guido van Rossum3886bb61998-12-04 18:50:17 +00005595DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005596INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00005597{
Barry Warsaw53699e91996-12-10 23:23:01 +00005598 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005599
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005600 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005601 posix_methods,
5602 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005603 (PyObject *)NULL,
5604 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005605 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005606
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005607 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005608 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005609 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005610 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005611 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005612
Barry Warsaw4a342091996-12-19 23:50:02 +00005613 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005614 return;
5615
Fred Drakebec628d1999-12-15 18:31:10 +00005616 if (setup_confname_tables(d))
5617 return;
5618
Barry Warsawca74da41999-02-09 19:31:45 +00005619 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005620
Guido van Rossumb3d39562000-01-31 18:41:26 +00005621#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00005622 if (posix_putenv_garbage == NULL)
5623 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00005624#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005625}