blob: 19d62b832c34a99af1f20a0ae258133c62afe0e2 [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 *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000116extern int fsync(int);
117extern int lstat(const char *, struct stat *);
118extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000119#endif
120
Guido van Rossum36bc6801995-06-14 22:54:23 +0000121#ifdef NeXT
122/* NeXT's <unistd.h> and <utime.h> aren't worth much */
123#undef HAVE_UNISTD_H
124#undef HAVE_UTIME_H
Guido van Rossumb9f866c1997-05-22 15:12:39 +0000125#define HAVE_WAITPID
Guido van Rossum36bc6801995-06-14 22:54:23 +0000126/* #undef HAVE_GETCWD */
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000127#define UNION_WAIT /* This should really be checked for by autoconf */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000128#endif
129
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000130#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000131#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000132extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000133#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000134#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000135extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000136#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000137extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000138#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000139#endif
140#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000141extern int chdir(char *);
142extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000143#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000144extern int chdir(const char *);
145extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000146#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000147extern int chmod(const char *, mode_t);
148extern int chown(const char *, uid_t, gid_t);
149extern char *getcwd(char *, int);
150extern char *strerror(int);
151extern int link(const char *, const char *);
152extern int rename(const char *, const char *);
153extern int stat(const char *, struct stat *);
154extern int unlink(const char *);
155extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000156#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000157extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000158#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000159#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000160extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000161#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000162#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000163
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000164#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000165
Guido van Rossumb6775db1994-08-01 11:34:53 +0000166#ifdef HAVE_UTIME_H
167#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000168#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000169
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000170#ifdef HAVE_SYS_UTIME_H
171#include <sys/utime.h>
172#define HAVE_UTIME_H /* pretend we do for the rest of this file */
173#endif /* HAVE_SYS_UTIME_H */
174
Guido van Rossumb6775db1994-08-01 11:34:53 +0000175#ifdef HAVE_SYS_TIMES_H
176#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000177#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000178
179#ifdef HAVE_SYS_PARAM_H
180#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000181#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000182
183#ifdef HAVE_SYS_UTSNAME_H
184#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000185#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000186
187#ifndef MAXPATHLEN
188#define MAXPATHLEN 1024
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000189#endif /* MAXPATHLEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000190
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000191#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000192#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000193#define NAMLEN(dirent) strlen((dirent)->d_name)
194#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000195#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000196#include <direct.h>
197#define NAMLEN(dirent) strlen((dirent)->d_name)
198#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000199#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000200#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000201#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000202#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000203#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000204#endif
205#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000206#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000207#endif
208#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000209#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000210#endif
211#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000212
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000213#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214#include <direct.h>
215#include <io.h>
216#include <process.h>
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000217#define WINDOWS_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000218#include <windows.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000219#ifdef MS_WIN32
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000220#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000221#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000222#else /* 16-bit Windows */
223#include <dos.h>
224#include <ctype.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000225#endif /* MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000226#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000227
Guido van Rossumd48f2521997-12-05 22:19:34 +0000228#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000229#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000230#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000231
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000232#ifdef UNION_WAIT
233/* Emulate some macros on systems that have a union instead of macros */
234
235#ifndef WIFEXITED
236#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
237#endif
238
239#ifndef WEXITSTATUS
240#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
241#endif
242
243#ifndef WTERMSIG
244#define WTERMSIG(u_wait) ((u_wait).w_termsig)
245#endif
246
247#endif /* UNION_WAIT */
248
Greg Wardb48bc172000-03-01 21:51:56 +0000249/* Don't use the "_r" form if we don't need it (also, won't have a
250 prototype for it, at least on Solaris -- maybe others as well?). */
251#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
252#define USE_CTERMID_R
253#endif
254
255#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
256#define USE_TMPNAM_R
257#endif
258
Fred Drake699f3522000-06-29 21:12:41 +0000259/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000260#undef STAT
Fred Drake699f3522000-06-29 21:12:41 +0000261#ifdef MS_WIN64
262# define STAT _stati64
263# define FSTAT _fstati64
264# define STRUCT_STAT struct _stati64
265#else
266# define STAT stat
267# define FSTAT fstat
268# define STRUCT_STAT struct stat
269#endif
270
271
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000272/* Return a dictionary corresponding to the POSIX environment table */
273
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000274#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000275extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000276#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000277
Barry Warsaw53699e91996-12-10 23:23:01 +0000278static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000279convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000280{
Barry Warsaw53699e91996-12-10 23:23:01 +0000281 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000282 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000283 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000284 if (d == NULL)
285 return NULL;
286 if (environ == NULL)
287 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000288 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000289 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000290 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000291 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000292 char *p = strchr(*e, '=');
293 if (p == NULL)
294 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000295 k = PyString_FromStringAndSize(*e, (int)(p-*e));
296 if (k == NULL) {
297 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000298 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000299 }
300 v = PyString_FromString(p+1);
301 if (v == NULL) {
302 PyErr_Clear();
303 Py_DECREF(k);
304 continue;
305 }
306 if (PyDict_GetItem(d, k) == NULL) {
307 if (PyDict_SetItem(d, k, v) != 0)
308 PyErr_Clear();
309 }
310 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000311 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000312 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000313#if defined(PYOS_OS2)
314 {
315 APIRET rc;
316 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
317
318 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000319 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000320 PyObject *v = PyString_FromString(buffer);
321 PyDict_SetItemString(d, "BEGINLIBPATH", v);
322 Py_DECREF(v);
323 }
324 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
325 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
326 PyObject *v = PyString_FromString(buffer);
327 PyDict_SetItemString(d, "ENDLIBPATH", v);
328 Py_DECREF(v);
329 }
330 }
331#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000332 return d;
333}
334
335
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000336/* Set a POSIX-specific error from errno, and return NULL */
337
Barry Warsawd58d7641998-07-23 16:14:40 +0000338static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000339posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000340{
Barry Warsawca74da41999-02-09 19:31:45 +0000341 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000342}
Barry Warsawd58d7641998-07-23 16:14:40 +0000343static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000344posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000345{
Barry Warsawca74da41999-02-09 19:31:45 +0000346 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000347}
348
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000349#ifdef MS_WIN32
350static PyObject *
351win32_error(char* function, char* filename)
352{
Mark Hammond33a6da92000-08-15 00:46:38 +0000353 /* XXX We should pass the function name along in the future.
354 (_winreg.c also wants to pass the function name.)
355 This would however require an additional param to the
356 Windows error object, which is non-trivial.
357 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000358 errno = GetLastError();
359 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000360 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000361 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000362 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000363}
364#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000365
Guido van Rossumd48f2521997-12-05 22:19:34 +0000366#if defined(PYOS_OS2)
367/**********************************************************************
368 * Helper Function to Trim and Format OS/2 Messages
369 **********************************************************************/
370 static void
371os2_formatmsg(char *msgbuf, int msglen, char *reason)
372{
373 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
374
375 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
376 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
377
378 while (lastc > msgbuf && isspace(*lastc))
379 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
380 }
381
382 /* Add Optional Reason Text */
383 if (reason) {
384 strcat(msgbuf, " : ");
385 strcat(msgbuf, reason);
386 }
387}
388
389/**********************************************************************
390 * Decode an OS/2 Operating System Error Code
391 *
392 * A convenience function to lookup an OS/2 error code and return a
393 * text message we can use to raise a Python exception.
394 *
395 * Notes:
396 * The messages for errors returned from the OS/2 kernel reside in
397 * the file OSO001.MSG in the \OS2 directory hierarchy.
398 *
399 **********************************************************************/
400 static char *
401os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
402{
403 APIRET rc;
404 ULONG msglen;
405
406 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
407 Py_BEGIN_ALLOW_THREADS
408 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
409 errorcode, "oso001.msg", &msglen);
410 Py_END_ALLOW_THREADS
411
412 if (rc == NO_ERROR)
413 os2_formatmsg(msgbuf, msglen, reason);
414 else
415 sprintf(msgbuf, "unknown OS error #%d", errorcode);
416
417 return msgbuf;
418}
419
420/* Set an OS/2-specific error and return NULL. OS/2 kernel
421 errors are not in a global variable e.g. 'errno' nor are
422 they congruent with posix error numbers. */
423
424static PyObject * os2_error(int code)
425{
426 char text[1024];
427 PyObject *v;
428
429 os2_strerror(text, sizeof(text), code, "");
430
431 v = Py_BuildValue("(is)", code, text);
432 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000433 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000434 Py_DECREF(v);
435 }
436 return NULL; /* Signal to Python that an Exception is Pending */
437}
438
439#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000440
441/* POSIX generic methods */
442
Barry Warsaw53699e91996-12-10 23:23:01 +0000443static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000444posix_int(PyObject *args, char *format, int (*func)(int))
Guido van Rossum21142a01999-01-08 21:05:37 +0000445{
446 int fd;
447 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000448 if (!PyArg_ParseTuple(args, format, &fd))
Guido van Rossum21142a01999-01-08 21:05:37 +0000449 return NULL;
450 Py_BEGIN_ALLOW_THREADS
451 res = (*func)(fd);
452 Py_END_ALLOW_THREADS
453 if (res < 0)
454 return posix_error();
455 Py_INCREF(Py_None);
456 return Py_None;
457}
458
459
460static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000461posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000462{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000463 char *path1;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000464 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000465 if (!PyArg_ParseTuple(args, format, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000466 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000467 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000468 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000469 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000470 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000471 return posix_error_with_filename(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000472 Py_INCREF(Py_None);
473 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000474}
475
Barry Warsaw53699e91996-12-10 23:23:01 +0000476static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000477posix_2str(PyObject *args, char *format,
478 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000479{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000480 char *path1, *path2;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000481 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000482 if (!PyArg_ParseTuple(args, format, &path1, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000483 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000484 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000485 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000486 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000487 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000488 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000489 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000490 Py_INCREF(Py_None);
491 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000492}
493
Fred Drake699f3522000-06-29 21:12:41 +0000494/* pack a system stat C structure into the Python stat tuple
495 (used by posix_stat() and posix_fstat()) */
496static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000497_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000498{
499 PyObject *v = PyTuple_New(10);
500 if (v == NULL)
501 return NULL;
502
503 PyTuple_SetItem(v, 0, PyInt_FromLong((long)st.st_mode));
504#ifdef HAVE_LARGEFILE_SUPPORT
505 PyTuple_SetItem(v, 1, PyLong_FromLongLong((LONG_LONG)st.st_ino));
506#else
507 PyTuple_SetItem(v, 1, PyInt_FromLong((long)st.st_ino));
508#endif
509#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
510 PyTuple_SetItem(v, 2, PyLong_FromLongLong((LONG_LONG)st.st_dev));
511#else
512 PyTuple_SetItem(v, 2, PyInt_FromLong((long)st.st_dev));
513#endif
514 PyTuple_SetItem(v, 3, PyInt_FromLong((long)st.st_nlink));
515 PyTuple_SetItem(v, 4, PyInt_FromLong((long)st.st_uid));
516 PyTuple_SetItem(v, 5, PyInt_FromLong((long)st.st_gid));
517#ifdef HAVE_LARGEFILE_SUPPORT
518 PyTuple_SetItem(v, 6, PyLong_FromLongLong((LONG_LONG)st.st_size));
519#else
520 PyTuple_SetItem(v, 6, PyInt_FromLong(st.st_size));
521#endif
522#if SIZEOF_TIME_T > SIZEOF_LONG
523 PyTuple_SetItem(v, 7, PyLong_FromLongLong((LONG_LONG)st.st_atime));
524 PyTuple_SetItem(v, 8, PyLong_FromLongLong((LONG_LONG)st.st_mtime));
525 PyTuple_SetItem(v, 9, PyLong_FromLongLong((LONG_LONG)st.st_ctime));
526#else
527 PyTuple_SetItem(v, 7, PyInt_FromLong((long)st.st_atime));
528 PyTuple_SetItem(v, 8, PyInt_FromLong((long)st.st_mtime));
529 PyTuple_SetItem(v, 9, PyInt_FromLong((long)st.st_ctime));
530#endif
531
532 if (PyErr_Occurred()) {
533 Py_DECREF(v);
534 return NULL;
535 }
536
537 return v;
538}
539
540
Barry Warsaw53699e91996-12-10 23:23:01 +0000541static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000542posix_do_stat(PyObject *self, PyObject *args, char *format,
543 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000544{
Fred Drake699f3522000-06-29 21:12:41 +0000545 STRUCT_STAT st;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000546 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000547 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000548
549#ifdef MS_WIN32
550 int pathlen;
551 char pathcopy[MAX_PATH];
552#endif /* MS_WIN32 */
553
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000554 if (!PyArg_ParseTuple(args, format, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000555 return NULL;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000556
557#ifdef MS_WIN32
558 pathlen = strlen(path);
559 /* the library call can blow up if the file name is too long! */
560 if (pathlen > MAX_PATH) {
561 errno = ENAMETOOLONG;
562 return posix_error();
563 }
564
565 if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) {
Guido van Rossum19dde102000-05-03 02:44:55 +0000566 /* exception for specific or current drive root */
567 if (!((pathlen == 1) ||
568 ((pathlen == 3) &&
Guido van Rossumace88ae2000-04-21 18:54:45 +0000569 (path[1] == ':') &&
Guido van Rossum19dde102000-05-03 02:44:55 +0000570 (path[2] == '\\' || path[2] == '/'))))
Guido van Rossumace88ae2000-04-21 18:54:45 +0000571 {
572 strncpy(pathcopy, path, pathlen);
573 pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */
574 path = pathcopy;
575 }
576 }
577#endif /* MS_WIN32 */
578
Barry Warsaw53699e91996-12-10 23:23:01 +0000579 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000580 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000581 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000582 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000583 return posix_error_with_filename(path);
Fred Drake699f3522000-06-29 21:12:41 +0000584
585 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000586}
587
588
589/* POSIX methods */
590
Guido van Rossum94f6f721999-01-06 18:42:14 +0000591static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000592"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000593Test for access to a file.";
594
595static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000596posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000597{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000598 char *path;
599 int mode;
600 int res;
601
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000602 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000603 return NULL;
604 Py_BEGIN_ALLOW_THREADS
605 res = access(path, mode);
606 Py_END_ALLOW_THREADS
607 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000608}
609
Guido van Rossumd371ff11999-01-25 16:12:23 +0000610#ifndef F_OK
611#define F_OK 0
612#endif
613#ifndef R_OK
614#define R_OK 4
615#endif
616#ifndef W_OK
617#define W_OK 2
618#endif
619#ifndef X_OK
620#define X_OK 1
621#endif
622
623#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000624static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000625"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000626Return the name of the terminal device connected to 'fd'.";
627
628static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000629posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000630{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000631 int id;
632 char *ret;
633
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000634 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000635 return NULL;
636
Guido van Rossum94f6f721999-01-06 18:42:14 +0000637 ret = ttyname(id);
638 if (ret == NULL)
639 return(posix_error());
640 return(PyString_FromString(ret));
641}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000642#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000643
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000644#ifdef HAVE_CTERMID
645static char posix_ctermid__doc__[] =
646"ctermid() -> String\n\
647Return the name of the controlling terminal for this process.";
648
649static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000650posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000651{
652 char *ret;
653 char buffer[L_ctermid];
654
655 if (!PyArg_ParseTuple(args, ":ctermid"))
656 return NULL;
657
Greg Wardb48bc172000-03-01 21:51:56 +0000658#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000659 ret = ctermid_r(buffer);
660#else
661 ret = ctermid(buffer);
662#endif
663 if (ret == NULL)
664 return(posix_error());
665 return(PyString_FromString(buffer));
666}
667#endif
668
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000669static char posix_chdir__doc__[] =
670"chdir(path) -> None\n\
671Change the current working directory to the specified path.";
672
Barry Warsaw53699e91996-12-10 23:23:01 +0000673static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000674posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000675{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000676 return posix_1str(args, "s:chdir", chdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000677}
678
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000679
680static char posix_chmod__doc__[] =
681"chmod(path, mode) -> None\n\
682Change the access permissions of a file.";
683
Barry Warsaw53699e91996-12-10 23:23:01 +0000684static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000685posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000686{
Guido van Rossumffd15f52000-03-31 00:47:28 +0000687 char *path;
688 int i;
689 int res;
Guido van Rossum49679b42000-03-31 00:48:21 +0000690 if (!PyArg_ParseTuple(args, "si", &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000691 return NULL;
692 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000693 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000694 Py_END_ALLOW_THREADS
695 if (res < 0)
696 return posix_error_with_filename(path);
697 Py_INCREF(Py_None);
698 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000699}
700
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000701
Guido van Rossum21142a01999-01-08 21:05:37 +0000702#ifdef HAVE_FSYNC
703static char posix_fsync__doc__[] =
704"fsync(fildes) -> None\n\
705force write of file with filedescriptor to disk.";
706
707static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000708posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000709{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000710 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000711}
712#endif /* HAVE_FSYNC */
713
714#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000715
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000716#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000717extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
718#endif
719
Guido van Rossum21142a01999-01-08 21:05:37 +0000720static char posix_fdatasync__doc__[] =
721"fdatasync(fildes) -> None\n\
722force write of file with filedescriptor to disk.\n\
723 does not force update of metadata.";
724
725static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000726posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000727{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000728 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000729}
730#endif /* HAVE_FDATASYNC */
731
732
Fredrik Lundh10723342000-07-10 16:38:09 +0000733#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000734static char posix_chown__doc__[] =
735"chown(path, uid, gid) -> None\n\
736Change the owner and group id of path to the numeric uid and gid.";
737
Barry Warsaw53699e91996-12-10 23:23:01 +0000738static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000739posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000740{
Fredrik Lundh44328e62000-07-10 15:59:30 +0000741 char *path;
742 int uid, gid;
743 int res;
744 if (!PyArg_ParseTuple(args, "sii:chown", &path, &uid, &gid))
745 return NULL;
746 Py_BEGIN_ALLOW_THREADS
747 res = chown(path, (uid_t) uid, (gid_t) gid);
748 Py_END_ALLOW_THREADS
749 if (res < 0)
750 return posix_error_with_filename(path);
751 Py_INCREF(Py_None);
752 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000753}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000754#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000755
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000756
Guido van Rossum36bc6801995-06-14 22:54:23 +0000757#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000758static char posix_getcwd__doc__[] =
759"getcwd() -> path\n\
760Return a string representing the current working directory.";
761
Barry Warsaw53699e91996-12-10 23:23:01 +0000762static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000763posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000764{
765 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000766 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000767 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000768 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000769 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000770 res = getcwd(buf, sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +0000771 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000772 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000773 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000774 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000775}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000776#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000777
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000778
Guido van Rossumb6775db1994-08-01 11:34:53 +0000779#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000780static char posix_link__doc__[] =
781"link(src, dst) -> None\n\
782Create a hard link to a file.";
783
Barry Warsaw53699e91996-12-10 23:23:01 +0000784static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000785posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000786{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000787 return posix_2str(args, "ss:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000788}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000789#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000790
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000791
792static char posix_listdir__doc__[] =
793"listdir(path) -> list_of_strings\n\
794Return a list containing the names of the entries in the directory.\n\
795\n\
796 path: path of directory to list\n\
797\n\
798The list is in arbitrary order. It does not include the special\n\
799entries '.' and '..' even if they are present in the directory.";
800
Barry Warsaw53699e91996-12-10 23:23:01 +0000801static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000802posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000803{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000804 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000805 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000806#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000807
Guido van Rossumb6775db1994-08-01 11:34:53 +0000808 char *name;
809 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000810 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000811 HANDLE hFindFile;
812 WIN32_FIND_DATA FileData;
813 char namebuf[MAX_PATH+5];
Tim Peters0bb44a42000-09-15 07:44:49 +0000814 char ch;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000815
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000816 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000817 return NULL;
818 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000819 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000820 return NULL;
821 }
822 strcpy(namebuf, name);
Tim Peters0bb44a42000-09-15 07:44:49 +0000823 ch = namebuf[len-1];
824 if (ch != '/' && ch != '\\' && ch != ':')
Guido van Rossumb6775db1994-08-01 11:34:53 +0000825 namebuf[len++] = '/';
826 strcpy(namebuf + len, "*.*");
827
Barry Warsaw53699e91996-12-10 23:23:01 +0000828 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000829 return NULL;
830
831 hFindFile = FindFirstFile(namebuf, &FileData);
832 if (hFindFile == INVALID_HANDLE_VALUE) {
833 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000834 if (errno == ERROR_FILE_NOT_FOUND)
835 return PyList_New(0);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000836 return win32_error("FindFirstFile", name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000837 }
838 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000839 if (FileData.cFileName[0] == '.' &&
840 (FileData.cFileName[1] == '\0' ||
841 FileData.cFileName[1] == '.' &&
842 FileData.cFileName[2] == '\0'))
843 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +0000844 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000845 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000846 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000847 d = NULL;
848 break;
849 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000850 if (PyList_Append(d, v) != 0) {
851 Py_DECREF(v);
852 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000853 d = NULL;
854 break;
855 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000856 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000857 } while (FindNextFile(hFindFile, &FileData) == TRUE);
858
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000859 if (FindClose(hFindFile) == FALSE)
860 return win32_error("FindClose", name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000861
862 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000863
Tim Peters0bb44a42000-09-15 07:44:49 +0000864#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000865
866#ifndef MAX_PATH
867#define MAX_PATH 250
868#endif
869 char *name, *pt;
870 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000871 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000872 char namebuf[MAX_PATH+5];
873 struct _find_t ep;
874
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000875 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000876 return NULL;
877 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000878 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000879 return NULL;
880 }
881 strcpy(namebuf, name);
882 for (pt = namebuf; *pt; pt++)
883 if (*pt == '/')
884 *pt = '\\';
885 if (namebuf[len-1] != '\\')
886 namebuf[len++] = '\\';
887 strcpy(namebuf + len, "*.*");
888
Barry Warsaw53699e91996-12-10 23:23:01 +0000889 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000890 return NULL;
891
892 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +0000893 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
894 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000895 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000896 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000897 }
898 do {
899 if (ep.name[0] == '.' &&
900 (ep.name[1] == '\0' ||
901 ep.name[1] == '.' &&
902 ep.name[2] == '\0'))
903 continue;
904 strcpy(namebuf, ep.name);
905 for (pt = namebuf; *pt; pt++)
906 if (isupper(*pt))
907 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +0000908 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000909 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000910 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000911 d = NULL;
912 break;
913 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000914 if (PyList_Append(d, v) != 0) {
915 Py_DECREF(v);
916 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000917 d = NULL;
918 break;
919 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000920 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000921 } while (_dos_findnext(&ep) == 0);
922
923 return d;
924
Tim Peters0bb44a42000-09-15 07:44:49 +0000925#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000926
927#ifndef MAX_PATH
928#define MAX_PATH CCHMAXPATH
929#endif
930 char *name, *pt;
931 int len;
932 PyObject *d, *v;
933 char namebuf[MAX_PATH+5];
934 HDIR hdir = 1;
935 ULONG srchcnt = 1;
936 FILEFINDBUF3 ep;
937 APIRET rc;
938
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000939 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000940 return NULL;
941 if (len >= MAX_PATH) {
942 PyErr_SetString(PyExc_ValueError, "path too long");
943 return NULL;
944 }
945 strcpy(namebuf, name);
946 for (pt = namebuf; *pt; pt++)
947 if (*pt == '/')
948 *pt = '\\';
949 if (namebuf[len-1] != '\\')
950 namebuf[len++] = '\\';
951 strcpy(namebuf + len, "*.*");
952
953 if ((d = PyList_New(0)) == NULL)
954 return NULL;
955
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000956 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
957 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000958 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000959 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
960 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
961 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000962
963 if (rc != NO_ERROR) {
964 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000965 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000966 }
967
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000968 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000969 do {
970 if (ep.achName[0] == '.'
971 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000972 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000973
974 strcpy(namebuf, ep.achName);
975
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000976 /* Leave Case of Name Alone -- In Native Form */
977 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000978
979 v = PyString_FromString(namebuf);
980 if (v == NULL) {
981 Py_DECREF(d);
982 d = NULL;
983 break;
984 }
985 if (PyList_Append(d, v) != 0) {
986 Py_DECREF(v);
987 Py_DECREF(d);
988 d = NULL;
989 break;
990 }
991 Py_DECREF(v);
992 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
993 }
994
995 return d;
996#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000997
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000998 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +0000999 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001000 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001001 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001002 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001003 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001004 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001005 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001006 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001007 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001008 closedir(dirp);
1009 return NULL;
1010 }
1011 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001012 if (ep->d_name[0] == '.' &&
1013 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001014 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001015 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001016 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001017 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001018 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001019 d = NULL;
1020 break;
1021 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001022 if (PyList_Append(d, v) != 0) {
1023 Py_DECREF(v);
1024 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001025 d = NULL;
1026 break;
1027 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001028 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001029 }
1030 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001031
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001032 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001033
Tim Peters0bb44a42000-09-15 07:44:49 +00001034#endif /* which OS */
1035} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001036
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001037static char posix_mkdir__doc__[] =
1038"mkdir(path [, mode=0777]) -> None\n\
1039Create a directory.";
1040
Barry Warsaw53699e91996-12-10 23:23:01 +00001041static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001042posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001043{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001044 int res;
1045 char *path;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001046 int mode = 0777;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001047 if (!PyArg_ParseTuple(args, "s|i:mkdir", &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001048 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001049 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001050#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001051 res = mkdir(path);
1052#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001053 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001054#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001055 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001056 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001057 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001058 Py_INCREF(Py_None);
1059 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001060}
1061
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001062
Guido van Rossumb6775db1994-08-01 11:34:53 +00001063#ifdef HAVE_NICE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001064static char posix_nice__doc__[] =
1065"nice(inc) -> new_priority\n\
1066Decrease the priority of process and return new priority.";
1067
Barry Warsaw53699e91996-12-10 23:23:01 +00001068static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001069posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001070{
1071 int increment, value;
1072
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001073 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001074 return NULL;
1075 value = nice(increment);
1076 if (value == -1)
1077 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001078 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001079}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001080#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001081
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001082
1083static char posix_rename__doc__[] =
1084"rename(old, new) -> None\n\
1085Rename a file or directory.";
1086
Barry Warsaw53699e91996-12-10 23:23:01 +00001087static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001088posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001089{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001090 return posix_2str(args, "ss:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001091}
1092
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001093
1094static char posix_rmdir__doc__[] =
1095"rmdir(path) -> None\n\
1096Remove a directory.";
1097
Barry Warsaw53699e91996-12-10 23:23:01 +00001098static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001099posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001100{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001101 return posix_1str(args, "s:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001102}
1103
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001104
1105static char posix_stat__doc__[] =
1106"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1107Perform a stat system call on the given path.";
1108
Barry Warsaw53699e91996-12-10 23:23:01 +00001109static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001110posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001111{
Fred Drake699f3522000-06-29 21:12:41 +00001112 return posix_do_stat(self, args, "s:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001113}
1114
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001115
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001116#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001117static char posix_system__doc__[] =
1118"system(command) -> exit_status\n\
1119Execute the command (a string) in a subshell.";
1120
Barry Warsaw53699e91996-12-10 23:23:01 +00001121static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001122posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001123{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001124 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001125 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001126 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001127 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001128 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001129 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001130 Py_END_ALLOW_THREADS
1131 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001132}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001133#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001134
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001135
1136static char posix_umask__doc__[] =
1137"umask(new_mask) -> old_mask\n\
1138Set the current numeric umask and return the previous umask.";
1139
Barry Warsaw53699e91996-12-10 23:23:01 +00001140static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001141posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001142{
1143 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001144 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001145 return NULL;
1146 i = umask(i);
1147 if (i < 0)
1148 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001149 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001150}
1151
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001152
1153static char posix_unlink__doc__[] =
1154"unlink(path) -> None\n\
1155Remove a file (same as remove(path)).";
1156
1157static char posix_remove__doc__[] =
1158"remove(path) -> None\n\
1159Remove a file (same as unlink(path)).";
1160
Barry Warsaw53699e91996-12-10 23:23:01 +00001161static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001162posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001163{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001164 return posix_1str(args, "s:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001165}
1166
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001167
Guido van Rossumb6775db1994-08-01 11:34:53 +00001168#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001169static char posix_uname__doc__[] =
1170"uname() -> (sysname, nodename, release, version, machine)\n\
1171Return a tuple identifying the current operating system.";
1172
Barry Warsaw53699e91996-12-10 23:23:01 +00001173static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001174posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001175{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001176 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001177 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001178 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001179 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001180 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001181 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001182 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001183 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001184 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001185 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001186 u.sysname,
1187 u.nodename,
1188 u.release,
1189 u.version,
1190 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001191}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001192#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001193
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001194
1195static char posix_utime__doc__[] =
1196"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001197utime(path, None) -> None\n\
1198Set the access and modified time of the file to the given values. If the\n\
1199second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001200
Barry Warsaw53699e91996-12-10 23:23:01 +00001201static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001202posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001203{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001204 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001205 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001206 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001207 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001208
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001209/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001210#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001211 struct utimbuf buf;
1212#define ATIME buf.actime
1213#define MTIME buf.modtime
1214#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001215#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001216 time_t buf[2];
1217#define ATIME buf[0]
1218#define MTIME buf[1]
1219#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001220#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001221
Barry Warsaw3cef8562000-05-01 16:17:24 +00001222 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001223 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001224 if (arg == Py_None) {
1225 /* optional time values not given */
1226 Py_BEGIN_ALLOW_THREADS
1227 res = utime(path, NULL);
1228 Py_END_ALLOW_THREADS
1229 }
1230 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1231 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001232 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001233 return NULL;
1234 }
1235 else {
1236 ATIME = atime;
1237 MTIME = mtime;
1238 Py_BEGIN_ALLOW_THREADS
1239 res = utime(path, UTIME_ARG);
1240 Py_END_ALLOW_THREADS
1241 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001242 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001243 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001244 Py_INCREF(Py_None);
1245 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001246#undef UTIME_ARG
1247#undef ATIME
1248#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001249}
1250
Guido van Rossum85e3b011991-06-03 12:42:10 +00001251
Guido van Rossum3b066191991-06-04 19:40:25 +00001252/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001253
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001254static char posix__exit__doc__[] =
1255"_exit(status)\n\
1256Exit to the system with specified status, without normal exit processing.";
1257
Barry Warsaw53699e91996-12-10 23:23:01 +00001258static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001259posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001260{
1261 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001262 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001263 return NULL;
1264 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001265 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001266}
1267
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001268
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001269#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001270static char posix_execv__doc__[] =
1271"execv(path, args)\n\
1272Execute an executable path with arguments, replacing current process.\n\
1273\n\
1274 path: path of executable file\n\
1275 args: tuple or list of strings";
1276
Barry Warsaw53699e91996-12-10 23:23:01 +00001277static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001278posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001279{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001280 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001281 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001282 char **argvlist;
1283 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001284 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001285
Guido van Rossum89b33251993-10-22 14:26:06 +00001286 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001287 argv is a list or tuple of strings. */
1288
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001289 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001290 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001291 if (PyList_Check(argv)) {
1292 argc = PyList_Size(argv);
1293 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001294 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001295 else if (PyTuple_Check(argv)) {
1296 argc = PyTuple_Size(argv);
1297 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001298 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001299 else {
Fred Drake661ea262000-10-24 19:57:45 +00001300 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001301 return NULL;
1302 }
1303
1304 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001305 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001306 return NULL;
1307 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001308
Barry Warsaw53699e91996-12-10 23:23:01 +00001309 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001310 if (argvlist == NULL)
1311 return NULL;
1312 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001313 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1314 PyMem_DEL(argvlist);
Guido van Rossum50422b42000-04-26 20:34:28 +00001315 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001316 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001317 return NULL;
1318
Guido van Rossum85e3b011991-06-03 12:42:10 +00001319 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001320 }
1321 argvlist[argc] = NULL;
1322
Guido van Rossumb6775db1994-08-01 11:34:53 +00001323#ifdef BAD_EXEC_PROTOTYPES
1324 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001325#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001326 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001327#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001328
Guido van Rossum85e3b011991-06-03 12:42:10 +00001329 /* If we get here it's definitely an error */
1330
Barry Warsaw53699e91996-12-10 23:23:01 +00001331 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001332 return posix_error();
1333}
1334
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001335
1336static char posix_execve__doc__[] =
1337"execve(path, args, env)\n\
1338Execute a path with arguments and environment, replacing current process.\n\
1339\n\
1340 path: path of executable file\n\
1341 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001342 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001343
Barry Warsaw53699e91996-12-10 23:23:01 +00001344static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001345posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001346{
1347 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001348 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001349 char **argvlist;
1350 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001351 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001352 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001353 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001354
1355 /* execve has three arguments: (path, argv, env), where
1356 argv is a list or tuple of strings and env is a dictionary
1357 like posix.environ. */
1358
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001359 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001360 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001361 if (PyList_Check(argv)) {
1362 argc = PyList_Size(argv);
1363 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001364 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001365 else if (PyTuple_Check(argv)) {
1366 argc = PyTuple_Size(argv);
1367 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001368 }
1369 else {
Fred Drake661ea262000-10-24 19:57:45 +00001370 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001371 return NULL;
1372 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001373 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001374 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001375 return NULL;
1376 }
1377
Guido van Rossum50422b42000-04-26 20:34:28 +00001378 if (argc == 0) {
1379 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001380 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001381 return NULL;
1382 }
1383
Barry Warsaw53699e91996-12-10 23:23:01 +00001384 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001385 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001386 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001387 return NULL;
1388 }
1389 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001390 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001391 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001392 &argvlist[i]))
1393 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001394 goto fail_1;
1395 }
1396 }
1397 argvlist[argc] = NULL;
1398
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001399 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001400 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001401 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001402 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001403 goto fail_1;
1404 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001405 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001406 keys = PyMapping_Keys(env);
1407 vals = PyMapping_Values(env);
1408 if (!keys || !vals)
1409 goto fail_2;
1410
1411 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001412 char *p, *k, *v;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001413
1414 key = PyList_GetItem(keys, pos);
1415 val = PyList_GetItem(vals, pos);
1416 if (!key || !val)
1417 goto fail_2;
1418
Fred Drake661ea262000-10-24 19:57:45 +00001419 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1420 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001421 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001422 goto fail_2;
1423 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001424
1425#if defined(PYOS_OS2)
1426 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1427 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1428#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001429 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001430 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001431 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001432 goto fail_2;
1433 }
1434 sprintf(p, "%s=%s", k, v);
1435 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001436#if defined(PYOS_OS2)
1437 }
1438#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001439 }
1440 envlist[envc] = 0;
1441
Guido van Rossumb6775db1994-08-01 11:34:53 +00001442
1443#ifdef BAD_EXEC_PROTOTYPES
1444 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001445#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001446 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001447#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001448
1449 /* If we get here it's definitely an error */
1450
1451 (void) posix_error();
1452
1453 fail_2:
1454 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001455 PyMem_DEL(envlist[envc]);
1456 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001457 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001458 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001459 Py_XDECREF(vals);
1460 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001461 return NULL;
1462}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001463#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001464
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001465
Guido van Rossuma1065681999-01-25 23:20:23 +00001466#ifdef HAVE_SPAWNV
1467static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001468"spawnv(mode, path, args)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001469Execute an executable path with arguments, replacing current process.\n\
1470\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001471 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001472 path: path of executable file\n\
1473 args: tuple or list of strings";
1474
1475static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001476posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001477{
1478 char *path;
1479 PyObject *argv;
1480 char **argvlist;
1481 int mode, i, argc;
Fred Drake699f3522000-06-29 21:12:41 +00001482 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001483 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001484
1485 /* spawnv has three arguments: (mode, path, argv), where
1486 argv is a list or tuple of strings. */
1487
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001488 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001489 return NULL;
1490 if (PyList_Check(argv)) {
1491 argc = PyList_Size(argv);
1492 getitem = PyList_GetItem;
1493 }
1494 else if (PyTuple_Check(argv)) {
1495 argc = PyTuple_Size(argv);
1496 getitem = PyTuple_GetItem;
1497 }
1498 else {
Fred Drake661ea262000-10-24 19:57:45 +00001499 PyErr_SetString(PyExc_TypeError, "spawmv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001500 return NULL;
1501 }
1502
1503 argvlist = PyMem_NEW(char *, argc+1);
1504 if (argvlist == NULL)
1505 return NULL;
1506 for (i = 0; i < argc; i++) {
1507 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1508 PyMem_DEL(argvlist);
Fred Drake137507e2000-06-01 02:02:46 +00001509 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001510 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001511 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001512 }
1513 }
1514 argvlist[argc] = NULL;
1515
Guido van Rossum246bc171999-02-01 23:54:31 +00001516 if (mode == _OLD_P_OVERLAY)
1517 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001518 spawnval = _spawnv(mode, path, argvlist);
Guido van Rossuma1065681999-01-25 23:20:23 +00001519
1520 PyMem_DEL(argvlist);
1521
Fred Drake699f3522000-06-29 21:12:41 +00001522 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001523 return posix_error();
1524 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001525#if SIZEOF_LONG == SIZEOF_VOID_P
1526 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001527#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001528 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001529#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001530}
1531
1532
1533static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001534"spawnve(mode, path, args, env)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001535Execute a path with arguments and environment, replacing current process.\n\
1536\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001537 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001538 path: path of executable file\n\
1539 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001540 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001541
1542static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001543posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001544{
1545 char *path;
1546 PyObject *argv, *env;
1547 char **argvlist;
1548 char **envlist;
1549 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1550 int mode, i, pos, argc, envc;
Fred Drake699f3522000-06-29 21:12:41 +00001551 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001552 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001553
1554 /* spawnve has four arguments: (mode, path, argv, env), where
1555 argv is a list or tuple of strings and env is a dictionary
1556 like posix.environ. */
1557
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001558 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001559 return NULL;
1560 if (PyList_Check(argv)) {
1561 argc = PyList_Size(argv);
1562 getitem = PyList_GetItem;
1563 }
1564 else if (PyTuple_Check(argv)) {
1565 argc = PyTuple_Size(argv);
1566 getitem = PyTuple_GetItem;
1567 }
1568 else {
Fred Drake661ea262000-10-24 19:57:45 +00001569 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001570 return NULL;
1571 }
1572 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001573 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001574 return NULL;
1575 }
1576
1577 argvlist = PyMem_NEW(char *, argc+1);
1578 if (argvlist == NULL) {
1579 PyErr_NoMemory();
1580 return NULL;
1581 }
1582 for (i = 0; i < argc; i++) {
1583 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001584 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001585 &argvlist[i]))
1586 {
1587 goto fail_1;
1588 }
1589 }
1590 argvlist[argc] = NULL;
1591
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001592 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001593 envlist = PyMem_NEW(char *, i + 1);
1594 if (envlist == NULL) {
1595 PyErr_NoMemory();
1596 goto fail_1;
1597 }
1598 envc = 0;
1599 keys = PyMapping_Keys(env);
1600 vals = PyMapping_Values(env);
1601 if (!keys || !vals)
1602 goto fail_2;
1603
1604 for (pos = 0; pos < i; pos++) {
1605 char *p, *k, *v;
1606
1607 key = PyList_GetItem(keys, pos);
1608 val = PyList_GetItem(vals, pos);
1609 if (!key || !val)
1610 goto fail_2;
1611
Fred Drake661ea262000-10-24 19:57:45 +00001612 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1613 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001614 {
1615 goto fail_2;
1616 }
1617 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1618 if (p == NULL) {
1619 PyErr_NoMemory();
1620 goto fail_2;
1621 }
1622 sprintf(p, "%s=%s", k, v);
1623 envlist[envc++] = p;
1624 }
1625 envlist[envc] = 0;
1626
Guido van Rossum246bc171999-02-01 23:54:31 +00001627 if (mode == _OLD_P_OVERLAY)
1628 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001629 spawnval = _spawnve(mode, path, argvlist, envlist);
1630 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001631 (void) posix_error();
1632 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001633#if SIZEOF_LONG == SIZEOF_VOID_P
1634 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001635#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001636 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001637#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001638
1639 fail_2:
1640 while (--envc >= 0)
1641 PyMem_DEL(envlist[envc]);
1642 PyMem_DEL(envlist);
1643 fail_1:
1644 PyMem_DEL(argvlist);
1645 Py_XDECREF(vals);
1646 Py_XDECREF(keys);
1647 return res;
1648}
1649#endif /* HAVE_SPAWNV */
1650
1651
Guido van Rossumad0ee831995-03-01 10:34:45 +00001652#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001653static char posix_fork__doc__[] =
1654"fork() -> pid\n\
1655Fork a child process.\n\
1656\n\
1657Return 0 to child process and PID of child to parent process.";
1658
Barry Warsaw53699e91996-12-10 23:23:01 +00001659static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001660posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001661{
1662 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001663 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001664 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001665 pid = fork();
1666 if (pid == -1)
1667 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001668 if (pid == 0)
1669 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001670 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001671}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001672#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001673
Fred Drake8cef4cf2000-06-28 16:40:38 +00001674#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1675#ifdef HAVE_PTY_H
1676#include <pty.h>
1677#else
1678#ifdef HAVE_LIBUTIL_H
1679#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001680#endif /* HAVE_LIBUTIL_H */
1681#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001682#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001683
Thomas Wouters70c21a12000-07-14 14:28:33 +00001684#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001685static char posix_openpty__doc__[] =
1686"openpty() -> (master_fd, slave_fd)\n\
1687Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1688
1689static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001690posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001691{
1692 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001693#ifndef HAVE_OPENPTY
1694 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001695#endif
1696
Fred Drake8cef4cf2000-06-28 16:40:38 +00001697 if (!PyArg_ParseTuple(args, ":openpty"))
1698 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001699
1700#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001701 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1702 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001703#else
1704 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1705 if (slave_name == NULL)
1706 return posix_error();
1707
1708 slave_fd = open(slave_name, O_RDWR);
1709 if (slave_fd < 0)
1710 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001711#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001712
Fred Drake8cef4cf2000-06-28 16:40:38 +00001713 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001714
Fred Drake8cef4cf2000-06-28 16:40:38 +00001715}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001716#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001717
1718#ifdef HAVE_FORKPTY
1719static char posix_forkpty__doc__[] =
1720"forkpty() -> (pid, master_fd)\n\
1721Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1722Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1723To both, return fd of newly opened pseudo-terminal.\n";
1724
1725static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001726posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001727{
1728 int master_fd, pid;
1729
1730 if (!PyArg_ParseTuple(args, ":forkpty"))
1731 return NULL;
1732 pid = forkpty(&master_fd, NULL, NULL, NULL);
1733 if (pid == -1)
1734 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001735 if (pid == 0)
1736 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001737 return Py_BuildValue("(ii)", pid, master_fd);
1738}
1739#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001740
Guido van Rossumad0ee831995-03-01 10:34:45 +00001741#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001742static char posix_getegid__doc__[] =
1743"getegid() -> egid\n\
1744Return the current process's effective group id.";
1745
Barry Warsaw53699e91996-12-10 23:23:01 +00001746static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001747posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001748{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001749 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001750 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001751 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001752}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001753#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001754
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001755
Guido van Rossumad0ee831995-03-01 10:34:45 +00001756#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001757static char posix_geteuid__doc__[] =
1758"geteuid() -> euid\n\
1759Return the current process's effective user id.";
1760
Barry Warsaw53699e91996-12-10 23:23:01 +00001761static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001762posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001763{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001764 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001765 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001766 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001767}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001768#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001769
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001770
Guido van Rossumad0ee831995-03-01 10:34:45 +00001771#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001772static char posix_getgid__doc__[] =
1773"getgid() -> gid\n\
1774Return the current process's group id.";
1775
Barry Warsaw53699e91996-12-10 23:23:01 +00001776static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001777posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001778{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001779 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001780 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001781 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001782}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001783#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001784
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001785
1786static char posix_getpid__doc__[] =
1787"getpid() -> pid\n\
1788Return the current process id";
1789
Barry Warsaw53699e91996-12-10 23:23:01 +00001790static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001791posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001792{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001793 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001794 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001795 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001796}
1797
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001798
Fred Drakec9680921999-12-13 16:37:25 +00001799#ifdef HAVE_GETGROUPS
1800static char posix_getgroups__doc__[] = "\
1801getgroups() -> list of group IDs\n\
1802Return list of supplemental group IDs for the process.";
1803
1804static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001805posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00001806{
1807 PyObject *result = NULL;
1808
1809 if (PyArg_ParseTuple(args, ":getgroups")) {
1810#ifdef NGROUPS_MAX
1811#define MAX_GROUPS NGROUPS_MAX
1812#else
1813 /* defined to be 16 on Solaris7, so this should be a small number */
1814#define MAX_GROUPS 64
1815#endif
1816 gid_t grouplist[MAX_GROUPS];
1817 int n;
1818
1819 n = getgroups(MAX_GROUPS, grouplist);
1820 if (n < 0)
1821 posix_error();
1822 else {
1823 result = PyList_New(n);
1824 if (result != NULL) {
1825 PyObject *o;
1826 int i;
1827 for (i = 0; i < n; ++i) {
1828 o = PyInt_FromLong((long)grouplist[i]);
1829 if (o == NULL) {
1830 Py_DECREF(result);
1831 result = NULL;
1832 break;
1833 }
1834 PyList_SET_ITEM(result, i, o);
1835 }
1836 }
1837 }
1838 }
1839 return result;
1840}
1841#endif
1842
Guido van Rossumb6775db1994-08-01 11:34:53 +00001843#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001844static char posix_getpgrp__doc__[] =
1845"getpgrp() -> pgrp\n\
1846Return the current process group id.";
1847
Barry Warsaw53699e91996-12-10 23:23:01 +00001848static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001849posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00001850{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001851 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00001852 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001853#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00001854 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001855#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00001856 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001857#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00001858}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001859#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00001860
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001861
Guido van Rossumb6775db1994-08-01 11:34:53 +00001862#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001863static char posix_setpgrp__doc__[] =
1864"setpgrp() -> None\n\
1865Make this process a session leader.";
1866
Barry Warsaw53699e91996-12-10 23:23:01 +00001867static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001868posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00001869{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001870 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00001871 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00001872#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00001873 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001874#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001875 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001876#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00001877 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001878 Py_INCREF(Py_None);
1879 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00001880}
1881
Guido van Rossumb6775db1994-08-01 11:34:53 +00001882#endif /* HAVE_SETPGRP */
1883
Guido van Rossumad0ee831995-03-01 10:34:45 +00001884#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001885static char posix_getppid__doc__[] =
1886"getppid() -> ppid\n\
1887Return the parent's process id.";
1888
Barry Warsaw53699e91996-12-10 23:23:01 +00001889static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001890posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001891{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001892 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001893 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001894 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001895}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001896#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001897
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001898
Fred Drake12c6e2d1999-12-14 21:25:03 +00001899#ifdef HAVE_GETLOGIN
1900static char posix_getlogin__doc__[] = "\
1901getlogin() -> string\n\
1902Return the actual login name.";
1903
1904static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001905posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00001906{
1907 PyObject *result = NULL;
1908
1909 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00001910 char *name;
1911 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00001912
Fred Drakea30680b2000-12-06 21:24:28 +00001913 errno = 0;
1914 name = getlogin();
1915 if (name == NULL) {
1916 if (errno)
1917 posix_error();
1918 else
1919 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00001920 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00001921 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00001922 else
1923 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00001924 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00001925 }
1926 return result;
1927}
1928#endif
1929
Guido van Rossumad0ee831995-03-01 10:34:45 +00001930#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001931static char posix_getuid__doc__[] =
1932"getuid() -> uid\n\
1933Return the current process's user id.";
1934
Barry Warsaw53699e91996-12-10 23:23:01 +00001935static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001936posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001937{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001938 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001939 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001940 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001941}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001942#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001943
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001944
Guido van Rossumad0ee831995-03-01 10:34:45 +00001945#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001946static char posix_kill__doc__[] =
1947"kill(pid, sig) -> None\n\
1948Kill a process with a signal.";
1949
Barry Warsaw53699e91996-12-10 23:23:01 +00001950static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001951posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001952{
1953 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001954 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001955 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001956#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001957 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
1958 APIRET rc;
1959 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001960 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001961
1962 } else if (sig == XCPT_SIGNAL_KILLPROC) {
1963 APIRET rc;
1964 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001965 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001966
1967 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001968 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001969#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00001970 if (kill(pid, sig) == -1)
1971 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001972#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001973 Py_INCREF(Py_None);
1974 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001975}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001976#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001977
Guido van Rossumc0125471996-06-28 18:55:32 +00001978#ifdef HAVE_PLOCK
1979
1980#ifdef HAVE_SYS_LOCK_H
1981#include <sys/lock.h>
1982#endif
1983
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001984static char posix_plock__doc__[] =
1985"plock(op) -> None\n\
1986Lock program segments into memory.";
1987
Barry Warsaw53699e91996-12-10 23:23:01 +00001988static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001989posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00001990{
1991 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001992 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00001993 return NULL;
1994 if (plock(op) == -1)
1995 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001996 Py_INCREF(Py_None);
1997 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00001998}
1999#endif
2000
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002001
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002002#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002003static char posix_popen__doc__[] =
2004"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2005Open a pipe to/from a command returning a file object.";
2006
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002007#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002008static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002009async_system(const char *command)
2010{
2011 char *p, errormsg[256], args[1024];
2012 RESULTCODES rcodes;
2013 APIRET rc;
2014 char *shell = getenv("COMSPEC");
2015 if (!shell)
2016 shell = "cmd";
2017
2018 strcpy(args, shell);
2019 p = &args[ strlen(args)+1 ];
2020 strcpy(p, "/c ");
2021 strcat(p, command);
2022 p += strlen(p) + 1;
2023 *p = '\0';
2024
2025 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002026 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002027 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002028 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002029 &rcodes, shell);
2030 return rc;
2031}
2032
Guido van Rossumd48f2521997-12-05 22:19:34 +00002033static FILE *
2034popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002035{
2036 HFILE rhan, whan;
2037 FILE *retfd = NULL;
2038 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2039
Guido van Rossumd48f2521997-12-05 22:19:34 +00002040 if (rc != NO_ERROR) {
2041 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002042 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002043 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002044
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002045 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2046 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002047
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002048 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2049 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002050
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002051 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2052 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002053
2054 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002055 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002056 }
2057
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002058 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2059 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002060
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002061 close(oldfd); /* And Close Saved STDOUT Handle */
2062 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002063
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002064 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2065 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002066
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002067 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2068 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002069
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002070 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2071 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002072
2073 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002074 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002075 }
2076
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002077 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2078 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002079
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002080 close(oldfd); /* And Close Saved STDIN Handle */
2081 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002082
Guido van Rossumd48f2521997-12-05 22:19:34 +00002083 } else {
2084 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002085 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002086 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002087}
2088
2089static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002090posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002091{
2092 char *name;
2093 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002094 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002095 FILE *fp;
2096 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002097 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002098 return NULL;
2099 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002100 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002101 Py_END_ALLOW_THREADS
2102 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002103 return os2_error(err);
2104
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002105 f = PyFile_FromFile(fp, name, mode, fclose);
2106 if (f != NULL)
2107 PyFile_SetBufSize(f, bufsize);
2108 return f;
2109}
2110
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002111#elif defined(MS_WIN32)
2112
2113/*
2114 * Portable 'popen' replacement for Win32.
2115 *
2116 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2117 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00002118 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002119 */
2120
2121#include <malloc.h>
2122#include <io.h>
2123#include <fcntl.h>
2124
2125/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2126#define POPEN_1 1
2127#define POPEN_2 2
2128#define POPEN_3 3
2129#define POPEN_4 4
2130
2131static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002132static int _PyPclose(FILE *file);
2133
2134/*
2135 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00002136 * for use when retrieving the process exit code. See _PyPclose() below
2137 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002138 */
2139static PyObject *_PyPopenProcs = NULL;
2140
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002141
2142/* popen that works from a GUI.
2143 *
2144 * The result of this function is a pipe (file) connected to the
2145 * processes stdin or stdout, depending on the requested mode.
2146 */
2147
2148static PyObject *
2149posix_popen(PyObject *self, PyObject *args)
2150{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002151 PyObject *f, *s;
2152 int tm = 0;
2153
2154 char *cmdstring;
2155 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002156 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002157 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002158 return NULL;
2159
2160 s = PyTuple_New(0);
2161
2162 if (*mode == 'r')
2163 tm = _O_RDONLY;
2164 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00002165 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002166 return NULL;
2167 } else
2168 tm = _O_WRONLY;
2169
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002170 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002171 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002172 return NULL;
2173 }
2174
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002175 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002176 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002177 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002178 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002179 else
2180 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2181
2182 return f;
2183}
2184
2185/* Variation on win32pipe.popen
2186 *
2187 * The result of this function is a pipe (file) connected to the
2188 * process's stdin, and a pipe connected to the process's stdout.
2189 */
2190
2191static PyObject *
2192win32_popen2(PyObject *self, PyObject *args)
2193{
2194 PyObject *f;
2195 int tm=0;
2196
2197 char *cmdstring;
2198 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002199 int bufsize = -1;
2200 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002201 return NULL;
2202
2203 if (*mode == 't')
2204 tm = _O_TEXT;
2205 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002206 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002207 return NULL;
2208 } else
2209 tm = _O_BINARY;
2210
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002211 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002212 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002213 return NULL;
2214 }
2215
2216 f = _PyPopen(cmdstring, tm, POPEN_2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002217
2218 return f;
2219}
2220
2221/*
2222 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002223 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002224 * The result of this function is 3 pipes - the process's stdin,
2225 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002226 */
2227
2228static PyObject *
2229win32_popen3(PyObject *self, PyObject *args)
2230{
2231 PyObject *f;
2232 int tm = 0;
2233
2234 char *cmdstring;
2235 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002236 int bufsize = -1;
2237 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002238 return NULL;
2239
2240 if (*mode == 't')
2241 tm = _O_TEXT;
2242 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002243 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002244 return NULL;
2245 } else
2246 tm = _O_BINARY;
2247
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002248 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002249 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002250 return NULL;
2251 }
2252
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002253 f = _PyPopen(cmdstring, tm, POPEN_3);
2254
2255 return f;
2256}
2257
2258/*
2259 * Variation on win32pipe.popen
2260 *
2261 * The result of this function is 2 pipes - the processes stdin,
2262 * and stdout+stderr combined as a single pipe.
2263 */
2264
2265static PyObject *
2266win32_popen4(PyObject *self, PyObject *args)
2267{
2268 PyObject *f;
2269 int tm = 0;
2270
2271 char *cmdstring;
2272 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002273 int bufsize = -1;
2274 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002275 return NULL;
2276
2277 if (*mode == 't')
2278 tm = _O_TEXT;
2279 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002280 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002281 return NULL;
2282 } else
2283 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002284
2285 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002286 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002287 return NULL;
2288 }
2289
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002290 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002291
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002292 return f;
2293}
2294
Mark Hammond08501372001-01-31 07:30:29 +00002295static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00002296_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002297 HANDLE hStdin,
2298 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00002299 HANDLE hStderr,
2300 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002301{
2302 PROCESS_INFORMATION piProcInfo;
2303 STARTUPINFO siStartInfo;
2304 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00002305 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002306 int i;
2307 int x;
2308
2309 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
2310 s1 = (char *)_alloca(i);
2311 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2312 return x;
2313 if (GetVersion() < 0x80000000) {
2314 /*
2315 * NT/2000
2316 */
2317 x = i + strlen(s3) + strlen(cmdstring) + 1;
2318 s2 = (char *)_alloca(x);
2319 ZeroMemory(s2, x);
2320 sprintf(s2, "%s%s%s", s1, s3, cmdstring);
2321 }
2322 else {
2323 /*
2324 * Oh gag, we're on Win9x. Use the workaround listed in
2325 * KB: Q150956
2326 */
Mark Hammond08501372001-01-31 07:30:29 +00002327 char modulepath[_MAX_PATH];
2328 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002329 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2330 for (i = x = 0; modulepath[i]; i++)
2331 if (modulepath[i] == '\\')
2332 x = i+1;
2333 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00002334 /* Create the full-name to w9xpopen, so we can test it exists */
2335 strncat(modulepath,
2336 szConsoleSpawn,
2337 (sizeof(modulepath)/sizeof(modulepath[0]))
2338 -strlen(modulepath));
2339 if (stat(modulepath, &statinfo) != 0) {
2340 /* Eeek - file-not-found - possibly an embedding
2341 situation - see if we can locate it in sys.prefix
2342 */
2343 strncpy(modulepath,
2344 Py_GetExecPrefix(),
2345 sizeof(modulepath)/sizeof(modulepath[0]));
2346 if (modulepath[strlen(modulepath)-1] != '\\')
2347 strcat(modulepath, "\\");
2348 strncat(modulepath,
2349 szConsoleSpawn,
2350 (sizeof(modulepath)/sizeof(modulepath[0]))
2351 -strlen(modulepath));
2352 /* No where else to look - raise an easily identifiable
2353 error, rather than leaving Windows to report
2354 "file not found" - as the user is probably blissfully
2355 unaware this shim EXE is used, and it will confuse them.
2356 (well, it confused me for a while ;-)
2357 */
2358 if (stat(modulepath, &statinfo) != 0) {
2359 PyErr_Format(PyExc_RuntimeError,
2360 "Can not locate '%s' which is needed "
2361 "for popen to work on this platform.",
2362 szConsoleSpawn);
2363 return FALSE;
2364 }
2365 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002366 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2367 strlen(modulepath) +
2368 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00002369
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002370 s2 = (char *)_alloca(x);
2371 ZeroMemory(s2, x);
2372 sprintf(
2373 s2,
Mark Hammond08501372001-01-31 07:30:29 +00002374 "%s \"%s%s%s\"",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002375 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002376 s1,
2377 s3,
2378 cmdstring);
2379 }
2380 }
2381
2382 /* Could be an else here to try cmd.exe / command.com in the path
2383 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00002384 else {
2385 PyErr_SetString(PyExc_RuntimeError, "Can not locate a COMSPEC environment variable to use as the shell");
2386 return FALSE;
2387 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002388
2389 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2390 siStartInfo.cb = sizeof(STARTUPINFO);
2391 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2392 siStartInfo.hStdInput = hStdin;
2393 siStartInfo.hStdOutput = hStdout;
2394 siStartInfo.hStdError = hStderr;
2395 siStartInfo.wShowWindow = SW_HIDE;
2396
2397 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002398 s2,
2399 NULL,
2400 NULL,
2401 TRUE,
2402 CREATE_NEW_CONSOLE,
2403 NULL,
2404 NULL,
2405 &siStartInfo,
2406 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002407 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002408 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002409
Mark Hammondb37a3732000-08-14 04:47:33 +00002410 /* Return process handle */
2411 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002412 return TRUE;
2413 }
Mark Hammond08501372001-01-31 07:30:29 +00002414 win32_error("CreateProcess", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002415 return FALSE;
2416}
2417
2418/* The following code is based off of KB: Q190351 */
2419
2420static PyObject *
2421_PyPopen(char *cmdstring, int mode, int n)
2422{
2423 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2424 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00002425 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002426
2427 SECURITY_ATTRIBUTES saAttr;
2428 BOOL fSuccess;
2429 int fd1, fd2, fd3;
2430 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00002431 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002432 PyObject *f;
2433
2434 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2435 saAttr.bInheritHandle = TRUE;
2436 saAttr.lpSecurityDescriptor = NULL;
2437
2438 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2439 return win32_error("CreatePipe", NULL);
2440
2441 /* Create new output read handle and the input write handle. Set
2442 * the inheritance properties to FALSE. Otherwise, the child inherits
2443 * the these handles; resulting in non-closeable handles to the pipes
2444 * being created. */
2445 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002446 GetCurrentProcess(), &hChildStdinWrDup, 0,
2447 FALSE,
2448 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002449 if (!fSuccess)
2450 return win32_error("DuplicateHandle", NULL);
2451
2452 /* Close the inheritable version of ChildStdin
2453 that we're using. */
2454 CloseHandle(hChildStdinWr);
2455
2456 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2457 return win32_error("CreatePipe", NULL);
2458
2459 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002460 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2461 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002462 if (!fSuccess)
2463 return win32_error("DuplicateHandle", NULL);
2464
2465 /* Close the inheritable version of ChildStdout
2466 that we're using. */
2467 CloseHandle(hChildStdoutRd);
2468
2469 if (n != POPEN_4) {
2470 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2471 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002472 fSuccess = DuplicateHandle(GetCurrentProcess(),
2473 hChildStderrRd,
2474 GetCurrentProcess(),
2475 &hChildStderrRdDup, 0,
2476 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002477 if (!fSuccess)
2478 return win32_error("DuplicateHandle", NULL);
2479 /* Close the inheritable version of ChildStdErr that we're using. */
2480 CloseHandle(hChildStderrRd);
2481 }
2482
2483 switch (n) {
2484 case POPEN_1:
2485 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2486 case _O_WRONLY | _O_TEXT:
2487 /* Case for writing to child Stdin in text mode. */
2488 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2489 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002490 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002491 PyFile_SetBufSize(f, 0);
2492 /* We don't care about these pipes anymore, so close them. */
2493 CloseHandle(hChildStdoutRdDup);
2494 CloseHandle(hChildStderrRdDup);
2495 break;
2496
2497 case _O_RDONLY | _O_TEXT:
2498 /* Case for reading from child Stdout in text mode. */
2499 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2500 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002501 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002502 PyFile_SetBufSize(f, 0);
2503 /* We don't care about these pipes anymore, so close them. */
2504 CloseHandle(hChildStdinWrDup);
2505 CloseHandle(hChildStderrRdDup);
2506 break;
2507
2508 case _O_RDONLY | _O_BINARY:
2509 /* Case for readinig from child Stdout in binary mode. */
2510 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2511 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002512 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002513 PyFile_SetBufSize(f, 0);
2514 /* We don't care about these pipes anymore, so close them. */
2515 CloseHandle(hChildStdinWrDup);
2516 CloseHandle(hChildStderrRdDup);
2517 break;
2518
2519 case _O_WRONLY | _O_BINARY:
2520 /* Case for writing to child Stdin in binary mode. */
2521 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2522 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002523 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002524 PyFile_SetBufSize(f, 0);
2525 /* We don't care about these pipes anymore, so close them. */
2526 CloseHandle(hChildStdoutRdDup);
2527 CloseHandle(hChildStderrRdDup);
2528 break;
2529 }
Mark Hammondb37a3732000-08-14 04:47:33 +00002530 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002531 break;
2532
2533 case POPEN_2:
2534 case POPEN_4:
2535 {
2536 char *m1, *m2;
2537 PyObject *p1, *p2;
2538
2539 if (mode && _O_TEXT) {
2540 m1 = "r";
2541 m2 = "w";
2542 } else {
2543 m1 = "rb";
2544 m2 = "wb";
2545 }
2546
2547 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2548 f1 = _fdopen(fd1, m2);
2549 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2550 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002551 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002552 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00002553 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002554 PyFile_SetBufSize(p2, 0);
2555
2556 if (n != 4)
2557 CloseHandle(hChildStderrRdDup);
2558
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002559 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00002560 Py_XDECREF(p1);
2561 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00002562 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002563 break;
2564 }
2565
2566 case POPEN_3:
2567 {
2568 char *m1, *m2;
2569 PyObject *p1, *p2, *p3;
2570
2571 if (mode && _O_TEXT) {
2572 m1 = "r";
2573 m2 = "w";
2574 } else {
2575 m1 = "rb";
2576 m2 = "wb";
2577 }
2578
2579 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2580 f1 = _fdopen(fd1, m2);
2581 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2582 f2 = _fdopen(fd2, m1);
2583 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2584 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002585 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00002586 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
2587 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002588 PyFile_SetBufSize(p1, 0);
2589 PyFile_SetBufSize(p2, 0);
2590 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002591 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00002592 Py_XDECREF(p1);
2593 Py_XDECREF(p2);
2594 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00002595 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002596 break;
2597 }
2598 }
2599
2600 if (n == POPEN_4) {
2601 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002602 hChildStdinRd,
2603 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002604 hChildStdoutWr,
2605 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002606 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002607 }
2608 else {
2609 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002610 hChildStdinRd,
2611 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002612 hChildStderrWr,
2613 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002614 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002615 }
2616
Mark Hammondb37a3732000-08-14 04:47:33 +00002617 /*
2618 * Insert the files we've created into the process dictionary
2619 * all referencing the list with the process handle and the
2620 * initial number of files (see description below in _PyPclose).
2621 * Since if _PyPclose later tried to wait on a process when all
2622 * handles weren't closed, it could create a deadlock with the
2623 * child, we spend some energy here to try to ensure that we
2624 * either insert all file handles into the dictionary or none
2625 * at all. It's a little clumsy with the various popen modes
2626 * and variable number of files involved.
2627 */
2628 if (!_PyPopenProcs) {
2629 _PyPopenProcs = PyDict_New();
2630 }
2631
2632 if (_PyPopenProcs) {
2633 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
2634 int ins_rc[3];
2635
2636 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2637 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2638
2639 procObj = PyList_New(2);
2640 hProcessObj = PyLong_FromVoidPtr(hProcess);
2641 intObj = PyInt_FromLong(file_count);
2642
2643 if (procObj && hProcessObj && intObj) {
2644 PyList_SetItem(procObj,0,hProcessObj);
2645 PyList_SetItem(procObj,1,intObj);
2646
2647 fileObj[0] = PyLong_FromVoidPtr(f1);
2648 if (fileObj[0]) {
2649 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2650 fileObj[0],
2651 procObj);
2652 }
2653 if (file_count >= 2) {
2654 fileObj[1] = PyLong_FromVoidPtr(f2);
2655 if (fileObj[1]) {
2656 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2657 fileObj[1],
2658 procObj);
2659 }
2660 }
2661 if (file_count >= 3) {
2662 fileObj[2] = PyLong_FromVoidPtr(f3);
2663 if (fileObj[2]) {
2664 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2665 fileObj[2],
2666 procObj);
2667 }
2668 }
2669
2670 if (ins_rc[0] < 0 || !fileObj[0] ||
2671 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2672 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
2673 /* Something failed - remove any dictionary
2674 * entries that did make it.
2675 */
2676 if (!ins_rc[0] && fileObj[0]) {
2677 PyDict_DelItem(_PyPopenProcs,
2678 fileObj[0]);
2679 }
2680 if (!ins_rc[1] && fileObj[1]) {
2681 PyDict_DelItem(_PyPopenProcs,
2682 fileObj[1]);
2683 }
2684 if (!ins_rc[2] && fileObj[2]) {
2685 PyDict_DelItem(_PyPopenProcs,
2686 fileObj[2]);
2687 }
2688 }
2689 }
2690
2691 /*
2692 * Clean up our localized references for the dictionary keys
2693 * and value since PyDict_SetItem will Py_INCREF any copies
2694 * that got placed in the dictionary.
2695 */
2696 Py_XDECREF(procObj);
2697 Py_XDECREF(fileObj[0]);
2698 Py_XDECREF(fileObj[1]);
2699 Py_XDECREF(fileObj[2]);
2700 }
2701
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002702 /* Child is launched. Close the parents copy of those pipe
2703 * handles that only the child should have open. You need to
2704 * make sure that no handles to the write end of the output pipe
2705 * are maintained in this process or else the pipe will not close
2706 * when the child process exits and the ReadFile will hang. */
2707
2708 if (!CloseHandle(hChildStdinRd))
2709 return win32_error("CloseHandle", NULL);
2710
2711 if (!CloseHandle(hChildStdoutWr))
2712 return win32_error("CloseHandle", NULL);
2713
2714 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2715 return win32_error("CloseHandle", NULL);
2716
2717 return f;
2718}
Fredrik Lundh56055a42000-07-23 19:47:12 +00002719
2720/*
2721 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2722 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00002723 *
2724 * This function uses the _PyPopenProcs dictionary in order to map the
2725 * input file pointer to information about the process that was
2726 * originally created by the popen* call that created the file pointer.
2727 * The dictionary uses the file pointer as a key (with one entry
2728 * inserted for each file returned by the original popen* call) and a
2729 * single list object as the value for all files from a single call.
2730 * The list object contains the Win32 process handle at [0], and a file
2731 * count at [1], which is initialized to the total number of file
2732 * handles using that list.
2733 *
2734 * This function closes whichever handle it is passed, and decrements
2735 * the file count in the dictionary for the process handle pointed to
2736 * by this file. On the last close (when the file count reaches zero),
2737 * this function will wait for the child process and then return its
2738 * exit code as the result of the close() operation. This permits the
2739 * files to be closed in any order - it is always the close() of the
2740 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002741 */
Tim Peters736aa322000-09-01 06:51:24 +00002742
2743 /* RED_FLAG 31-Aug-2000 Tim
2744 * This is always called (today!) between a pair of
2745 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2746 * macros. So the thread running this has no valid thread state, as
2747 * far as Python is concerned. However, this calls some Python API
2748 * functions that cannot be called safely without a valid thread
2749 * state, in particular PyDict_GetItem.
2750 * As a temporary hack (although it may last for years ...), we
2751 * *rely* on not having a valid thread state in this function, in
2752 * order to create our own "from scratch".
2753 * This will deadlock if _PyPclose is ever called by a thread
2754 * holding the global lock.
2755 */
2756
Fredrik Lundh56055a42000-07-23 19:47:12 +00002757static int _PyPclose(FILE *file)
2758{
Fredrik Lundh20318932000-07-26 17:29:12 +00002759 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002760 DWORD exit_code;
2761 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00002762 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
2763 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00002764#ifdef WITH_THREAD
2765 PyInterpreterState* pInterpreterState;
2766 PyThreadState* pThreadState;
2767#endif
2768
Fredrik Lundh20318932000-07-26 17:29:12 +00002769 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00002770 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00002771 */
2772 result = fclose(file);
2773
Tim Peters736aa322000-09-01 06:51:24 +00002774#ifdef WITH_THREAD
2775 /* Bootstrap a valid thread state into existence. */
2776 pInterpreterState = PyInterpreterState_New();
2777 if (!pInterpreterState) {
2778 /* Well, we're hosed now! We don't have a thread
2779 * state, so can't call a nice error routine, or raise
2780 * an exception. Just die.
2781 */
2782 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00002783 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00002784 return -1; /* unreachable */
2785 }
2786 pThreadState = PyThreadState_New(pInterpreterState);
2787 if (!pThreadState) {
2788 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00002789 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00002790 return -1; /* unreachable */
2791 }
2792 /* Grab the global lock. Note that this will deadlock if the
2793 * current thread already has the lock! (see RED_FLAG comments
2794 * before this function)
2795 */
2796 PyEval_RestoreThread(pThreadState);
2797#endif
2798
Fredrik Lundh56055a42000-07-23 19:47:12 +00002799 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00002800 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2801 (procObj = PyDict_GetItem(_PyPopenProcs,
2802 fileObj)) != NULL &&
2803 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
2804 (intObj = PyList_GetItem(procObj,1)) != NULL) {
2805
2806 hProcess = PyLong_AsVoidPtr(hProcessObj);
2807 file_count = PyInt_AsLong(intObj);
2808
2809 if (file_count > 1) {
2810 /* Still other files referencing process */
2811 file_count--;
2812 PyList_SetItem(procObj,1,
2813 PyInt_FromLong(file_count));
2814 } else {
2815 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00002816 if (result != EOF &&
2817 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
2818 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00002819 /* Possible truncation here in 16-bit environments, but
2820 * real exit codes are just the lower byte in any event.
2821 */
2822 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002823 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00002824 /* Indicate failure - this will cause the file object
2825 * to raise an I/O error and translate the last Win32
2826 * error code from errno. We do have a problem with
2827 * last errors that overlap the normal errno table,
2828 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002829 */
Fredrik Lundh20318932000-07-26 17:29:12 +00002830 if (result != EOF) {
2831 /* If the error wasn't from the fclose(), then
2832 * set errno for the file object error handling.
2833 */
2834 errno = GetLastError();
2835 }
2836 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002837 }
2838
2839 /* Free up the native handle at this point */
2840 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00002841 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00002842
Mark Hammondb37a3732000-08-14 04:47:33 +00002843 /* Remove this file pointer from dictionary */
2844 PyDict_DelItem(_PyPopenProcs, fileObj);
2845
2846 if (PyDict_Size(_PyPopenProcs) == 0) {
2847 Py_DECREF(_PyPopenProcs);
2848 _PyPopenProcs = NULL;
2849 }
2850
2851 } /* if object retrieval ok */
2852
2853 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002854 } /* if _PyPopenProcs */
2855
Tim Peters736aa322000-09-01 06:51:24 +00002856#ifdef WITH_THREAD
2857 /* Tear down the thread & interpreter states.
2858 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00002859 * call the thread clear & delete functions, and indeed insist on
2860 * doing that themselves. The lock must be held during the clear, but
2861 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00002862 */
2863 PyInterpreterState_Clear(pInterpreterState);
2864 PyEval_ReleaseThread(pThreadState);
2865 PyInterpreterState_Delete(pInterpreterState);
2866#endif
2867
Fredrik Lundh56055a42000-07-23 19:47:12 +00002868 return result;
2869}
Tim Peters9acdd3a2000-09-01 19:26:36 +00002870
2871#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00002872static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002873posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00002874{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002875 char *name;
2876 char *mode = "r";
2877 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00002878 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00002879 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002880 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00002881 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002882 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002883 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00002884 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00002885 if (fp == NULL)
2886 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002887 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002888 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00002889 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002890 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00002891}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002892#endif
2893
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002894#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00002895
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002896
Guido van Rossumb6775db1994-08-01 11:34:53 +00002897#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002898static char posix_setuid__doc__[] =
2899"setuid(uid) -> None\n\
2900Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00002901static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002902posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002903{
2904 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002905 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002906 return NULL;
2907 if (setuid(uid) < 0)
2908 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002909 Py_INCREF(Py_None);
2910 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002911}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002912#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002913
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002914
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00002915#ifdef HAVE_SETEUID
2916static char posix_seteuid__doc__[] =
2917"seteuid(uid) -> None\n\
2918Set the current process's effective user id.";
2919static PyObject *
2920posix_seteuid (PyObject *self, PyObject *args)
2921{
2922 int euid;
2923 if (!PyArg_ParseTuple(args, "i", &euid)) {
2924 return NULL;
2925 } else if (seteuid(euid) < 0) {
2926 return posix_error();
2927 } else {
2928 Py_INCREF(Py_None);
2929 return Py_None;
2930 }
2931}
2932#endif /* HAVE_SETEUID */
2933
2934#ifdef HAVE_SETEGID
2935static char posix_setegid__doc__[] =
2936"setegid(gid) -> None\n\
2937Set the current process's effective group id.";
2938static PyObject *
2939posix_setegid (PyObject *self, PyObject *args)
2940{
2941 int egid;
2942 if (!PyArg_ParseTuple(args, "i", &egid)) {
2943 return NULL;
2944 } else if (setegid(egid) < 0) {
2945 return posix_error();
2946 } else {
2947 Py_INCREF(Py_None);
2948 return Py_None;
2949 }
2950}
2951#endif /* HAVE_SETEGID */
2952
2953#ifdef HAVE_SETREUID
2954static char posix_setreuid__doc__[] =
2955"seteuid(ruid, euid) -> None\n\
2956Set the current process's real and effective user ids.";
2957static PyObject *
2958posix_setreuid (PyObject *self, PyObject *args)
2959{
2960 int ruid, euid;
2961 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
2962 return NULL;
2963 } else if (setreuid(ruid, euid) < 0) {
2964 return posix_error();
2965 } else {
2966 Py_INCREF(Py_None);
2967 return Py_None;
2968 }
2969}
2970#endif /* HAVE_SETREUID */
2971
2972#ifdef HAVE_SETREGID
2973static char posix_setregid__doc__[] =
2974"setegid(rgid, egid) -> None\n\
2975Set the current process's real and effective group ids.";
2976static PyObject *
2977posix_setregid (PyObject *self, PyObject *args)
2978{
2979 int rgid, egid;
2980 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
2981 return NULL;
2982 } else if (setregid(rgid, egid) < 0) {
2983 return posix_error();
2984 } else {
2985 Py_INCREF(Py_None);
2986 return Py_None;
2987 }
2988}
2989#endif /* HAVE_SETREGID */
2990
Guido van Rossumb6775db1994-08-01 11:34:53 +00002991#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002992static char posix_setgid__doc__[] =
2993"setgid(gid) -> None\n\
2994Set the current process's group id.";
2995
Barry Warsaw53699e91996-12-10 23:23:01 +00002996static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002997posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002998{
2999 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003000 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003001 return NULL;
3002 if (setgid(gid) < 0)
3003 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003004 Py_INCREF(Py_None);
3005 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003006}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003007#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003008
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003009
Guido van Rossumb6775db1994-08-01 11:34:53 +00003010#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003011static char posix_waitpid__doc__[] =
3012"waitpid(pid, options) -> (pid, status)\n\
Guido van Rossumf377d572000-12-12 00:37:58 +00003013Wait for completion of a given child process.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003014
Barry Warsaw53699e91996-12-10 23:23:01 +00003015static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003016posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003017{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003018 int pid, options;
3019#ifdef UNION_WAIT
3020 union wait status;
3021#define status_i (status.w_status)
3022#else
3023 int status;
3024#define status_i status
3025#endif
3026 status_i = 0;
3027
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003028 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00003029 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003030 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003031#ifdef NeXT
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003032 pid = wait4(pid, &status, options, NULL);
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003033#else
3034 pid = waitpid(pid, &status, options);
3035#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003036 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00003037 if (pid == -1)
3038 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00003039 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003040 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00003041}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003042#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +00003043
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003044
Guido van Rossumad0ee831995-03-01 10:34:45 +00003045#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003046static char posix_wait__doc__[] =
3047"wait() -> (pid, status)\n\
3048Wait for completion of a child process.";
3049
Barry Warsaw53699e91996-12-10 23:23:01 +00003050static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003051posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00003052{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003053 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003054#ifdef UNION_WAIT
3055 union wait status;
3056#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003057#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003058 int status;
3059#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003060#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003061 if (!PyArg_ParseTuple(args, ":wait"))
3062 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003063 status_i = 0;
3064 Py_BEGIN_ALLOW_THREADS
3065 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00003066 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00003067 if (pid == -1)
3068 return posix_error();
3069 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003070 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003071#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00003072}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003073#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003074
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003075
3076static char posix_lstat__doc__[] =
3077"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
3078Like stat(path), but do not follow symbolic links.";
3079
Barry Warsaw53699e91996-12-10 23:23:01 +00003080static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003081posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003082{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003083#ifdef HAVE_LSTAT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003084 return posix_do_stat(self, args, "s:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003085#else /* !HAVE_LSTAT */
Fred Drake699f3522000-06-29 21:12:41 +00003086 return posix_do_stat(self, args, "s:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003087#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003088}
3089
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003090
Guido van Rossumb6775db1994-08-01 11:34:53 +00003091#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003092static char posix_readlink__doc__[] =
3093"readlink(path) -> path\n\
3094Return a string representing the path to which the symbolic link points.";
3095
Barry Warsaw53699e91996-12-10 23:23:01 +00003096static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003097posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003098{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003099 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003100 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003101 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003102 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003103 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003104 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00003105 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00003106 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003107 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003108 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00003109 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003110}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003111#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003112
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003113
Guido van Rossumb6775db1994-08-01 11:34:53 +00003114#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003115static char posix_symlink__doc__[] =
3116"symlink(src, dst) -> None\n\
3117Create a symbolic link.";
3118
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003119static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003120posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003121{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003122 return posix_2str(args, "ss:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003123}
3124#endif /* HAVE_SYMLINK */
3125
3126
3127#ifdef HAVE_TIMES
3128#ifndef HZ
3129#define HZ 60 /* Universal constant :-) */
3130#endif /* HZ */
3131
Guido van Rossumd48f2521997-12-05 22:19:34 +00003132#if defined(PYCC_VACPP) && defined(PYOS_OS2)
3133static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003134system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003135{
3136 ULONG value = 0;
3137
3138 Py_BEGIN_ALLOW_THREADS
3139 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
3140 Py_END_ALLOW_THREADS
3141
3142 return value;
3143}
3144
3145static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003146posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003147{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003148 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00003149 return NULL;
3150
3151 /* Currently Only Uptime is Provided -- Others Later */
3152 return Py_BuildValue("ddddd",
3153 (double)0 /* t.tms_utime / HZ */,
3154 (double)0 /* t.tms_stime / HZ */,
3155 (double)0 /* t.tms_cutime / HZ */,
3156 (double)0 /* t.tms_cstime / HZ */,
3157 (double)system_uptime() / 1000);
3158}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003159#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003160static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003161posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00003162{
3163 struct tms t;
3164 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003165 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00003166 return NULL;
3167 errno = 0;
3168 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00003169 if (c == (clock_t) -1)
3170 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003171 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00003172 (double)t.tms_utime / HZ,
3173 (double)t.tms_stime / HZ,
3174 (double)t.tms_cutime / HZ,
3175 (double)t.tms_cstime / HZ,
3176 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00003177}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003178#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003179#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003180
3181
Guido van Rossum87755a21996-09-07 00:59:43 +00003182#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003183#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00003184static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003185posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003186{
3187 FILETIME create, exit, kernel, user;
3188 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003189 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003190 return NULL;
3191 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003192 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
3193 /* The fields of a FILETIME structure are the hi and lo part
3194 of a 64-bit value expressed in 100 nanosecond units.
3195 1e7 is one second in such units; 1e-7 the inverse.
3196 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
3197 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003198 return Py_BuildValue(
3199 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003200 (double)(kernel.dwHighDateTime*429.4967296 +
3201 kernel.dwLowDateTime*1e-7),
3202 (double)(user.dwHighDateTime*429.4967296 +
3203 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00003204 (double)0,
3205 (double)0,
3206 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003207}
Guido van Rossum8d665e61996-06-26 18:22:49 +00003208#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003209
3210#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00003211static char posix_times__doc__[] =
3212"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
3213Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003214#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003215
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003216
Guido van Rossumb6775db1994-08-01 11:34:53 +00003217#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003218static char posix_setsid__doc__[] =
3219"setsid() -> None\n\
3220Call the system call setsid().";
3221
Barry Warsaw53699e91996-12-10 23:23:01 +00003222static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003223posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003224{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003225 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003226 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003227 if (setsid() < 0)
3228 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003229 Py_INCREF(Py_None);
3230 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003231}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003232#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003233
Guido van Rossumb6775db1994-08-01 11:34:53 +00003234#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003235static char posix_setpgid__doc__[] =
3236"setpgid(pid, pgrp) -> None\n\
3237Call the system call setpgid().";
3238
Barry Warsaw53699e91996-12-10 23:23:01 +00003239static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003240posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003241{
3242 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003243 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003244 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003245 if (setpgid(pid, pgrp) < 0)
3246 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003247 Py_INCREF(Py_None);
3248 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003249}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003250#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003251
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003252
Guido van Rossumb6775db1994-08-01 11:34:53 +00003253#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003254static char posix_tcgetpgrp__doc__[] =
3255"tcgetpgrp(fd) -> pgid\n\
3256Return the process group associated with the terminal given by a fd.";
3257
Barry Warsaw53699e91996-12-10 23:23:01 +00003258static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003259posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003260{
3261 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003262 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003263 return NULL;
3264 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003265 if (pgid < 0)
3266 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003267 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00003268}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003269#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00003270
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003271
Guido van Rossumb6775db1994-08-01 11:34:53 +00003272#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003273static char posix_tcsetpgrp__doc__[] =
3274"tcsetpgrp(fd, pgid) -> None\n\
3275Set the process group associated with the terminal given by a fd.";
3276
Barry Warsaw53699e91996-12-10 23:23:01 +00003277static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003278posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003279{
3280 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003281 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003282 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003283 if (tcsetpgrp(fd, pgid) < 0)
3284 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00003285 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00003286 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00003287}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003288#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00003289
Guido van Rossum687dd131993-05-17 08:34:16 +00003290/* Functions acting on file descriptors */
3291
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003292static char posix_open__doc__[] =
3293"open(filename, flag [, mode=0777]) -> fd\n\
3294Open a file (for low level IO).";
3295
Barry Warsaw53699e91996-12-10 23:23:01 +00003296static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003297posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003298{
3299 char *file;
3300 int flag;
3301 int mode = 0777;
3302 int fd;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003303 if (!PyArg_ParseTuple(args, "si|i", &file, &flag, &mode))
3304 return NULL;
3305
Barry Warsaw53699e91996-12-10 23:23:01 +00003306 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003307 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003308 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003309 if (fd < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003310 return posix_error_with_filename(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00003311 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003312}
3313
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003314
3315static char posix_close__doc__[] =
3316"close(fd) -> None\n\
3317Close a file descriptor (for low level IO).";
3318
Barry Warsaw53699e91996-12-10 23:23:01 +00003319static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003320posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003321{
3322 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003323 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003324 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003325 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003326 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003327 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003328 if (res < 0)
3329 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003330 Py_INCREF(Py_None);
3331 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003332}
3333
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003334
3335static char posix_dup__doc__[] =
3336"dup(fd) -> fd2\n\
3337Return a duplicate of a file descriptor.";
3338
Barry Warsaw53699e91996-12-10 23:23:01 +00003339static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003340posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003341{
3342 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003343 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003344 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003345 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003346 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003347 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003348 if (fd < 0)
3349 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003350 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003351}
3352
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003353
3354static char posix_dup2__doc__[] =
3355"dup2(fd, fd2) -> None\n\
3356Duplicate file descriptor.";
3357
Barry Warsaw53699e91996-12-10 23:23:01 +00003358static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003359posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003360{
3361 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003362 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00003363 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003364 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003365 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00003366 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003367 if (res < 0)
3368 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003369 Py_INCREF(Py_None);
3370 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003371}
3372
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003373
3374static char posix_lseek__doc__[] =
3375"lseek(fd, pos, how) -> newpos\n\
3376Set the current position of a file descriptor.";
3377
Barry Warsaw53699e91996-12-10 23:23:01 +00003378static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003379posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003380{
3381 int fd, how;
Fred Drake699f3522000-06-29 21:12:41 +00003382#ifdef MS_WIN64
3383 LONG_LONG pos, res;
3384#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003385 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003386#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003387 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003388 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003389 return NULL;
3390#ifdef SEEK_SET
3391 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3392 switch (how) {
3393 case 0: how = SEEK_SET; break;
3394 case 1: how = SEEK_CUR; break;
3395 case 2: how = SEEK_END; break;
3396 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003397#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003398
3399#if !defined(HAVE_LARGEFILE_SUPPORT)
3400 pos = PyInt_AsLong(posobj);
3401#else
3402 pos = PyLong_Check(posobj) ?
3403 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3404#endif
3405 if (PyErr_Occurred())
3406 return NULL;
3407
Barry Warsaw53699e91996-12-10 23:23:01 +00003408 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003409#ifdef MS_WIN64
3410 res = _lseeki64(fd, pos, how);
3411#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003412 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003413#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003414 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003415 if (res < 0)
3416 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003417
3418#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003419 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003420#else
3421 return PyLong_FromLongLong(res);
3422#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003423}
3424
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003425
3426static char posix_read__doc__[] =
3427"read(fd, buffersize) -> string\n\
3428Read a file descriptor.";
3429
Barry Warsaw53699e91996-12-10 23:23:01 +00003430static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003431posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003432{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003433 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003434 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003435 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003436 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003437 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003438 if (buffer == NULL)
3439 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003440 Py_BEGIN_ALLOW_THREADS
3441 n = read(fd, PyString_AsString(buffer), size);
3442 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003443 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003444 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003445 return posix_error();
3446 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003447 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003448 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003449 return buffer;
3450}
3451
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003452
3453static char posix_write__doc__[] =
3454"write(fd, string) -> byteswritten\n\
3455Write a string to a file descriptor.";
3456
Barry Warsaw53699e91996-12-10 23:23:01 +00003457static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003458posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003459{
3460 int fd, size;
3461 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003462 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003463 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003464 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003465 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003466 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003467 if (size < 0)
3468 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003469 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003470}
3471
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003472
3473static char posix_fstat__doc__[]=
3474"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3475Like stat(), but for an open file descriptor.";
3476
Barry Warsaw53699e91996-12-10 23:23:01 +00003477static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003478posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003479{
3480 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003481 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003482 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003483 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003484 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003485 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003486 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003487 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003488 if (res != 0)
3489 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00003490
3491 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003492}
3493
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003494
3495static char posix_fdopen__doc__[] =
3496"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3497Return an open file object connected to a file descriptor.";
3498
Barry Warsaw53699e91996-12-10 23:23:01 +00003499static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003500posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003501{
Guido van Rossum687dd131993-05-17 08:34:16 +00003502 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003503 char *mode = "r";
3504 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003505 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003506 PyObject *f;
3507 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003508 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003509
Barry Warsaw53699e91996-12-10 23:23:01 +00003510 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003511 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003512 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003513 if (fp == NULL)
3514 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003515 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003516 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003517 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003518 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003519}
3520
Skip Montanaro1517d842000-07-19 14:34:14 +00003521static char posix_isatty__doc__[] =
3522"isatty(fd) -> Boolean\n\
3523Return true if the file descriptor 'fd' is an open file descriptor\n\
Thomas Wouters12e15952000-10-03 16:54:24 +00003524connected to the slave end of a terminal.";
Skip Montanaro1517d842000-07-19 14:34:14 +00003525
3526static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00003527posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00003528{
3529 int fd;
3530 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3531 return NULL;
3532 return Py_BuildValue("i", isatty(fd));
3533}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003534
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003535#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003536static char posix_pipe__doc__[] =
3537"pipe() -> (read_end, write_end)\n\
3538Create a pipe.";
3539
Barry Warsaw53699e91996-12-10 23:23:01 +00003540static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003541posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003542{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003543#if defined(PYOS_OS2)
3544 HFILE read, write;
3545 APIRET rc;
3546
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003547 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003548 return NULL;
3549
3550 Py_BEGIN_ALLOW_THREADS
3551 rc = DosCreatePipe( &read, &write, 4096);
3552 Py_END_ALLOW_THREADS
3553 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003554 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003555
3556 return Py_BuildValue("(ii)", read, write);
3557#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003558#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003559 int fds[2];
3560 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003561 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003562 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003563 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003564 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003565 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003566 if (res != 0)
3567 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003568 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003569#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003570 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003571 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003572 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003573 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003574 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003575 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003576 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003577 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003578 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003579 return win32_error("CreatePipe", NULL);
Fred Drake699f3522000-06-29 21:12:41 +00003580 read_fd = _open_osfhandle((intptr_t)read, 0);
3581 write_fd = _open_osfhandle((intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003582 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003583#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003584#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003585}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003586#endif /* HAVE_PIPE */
3587
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003588
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003589#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003590static char posix_mkfifo__doc__[] =
3591"mkfifo(file, [, mode=0666]) -> None\n\
3592Create a FIFO (a POSIX named pipe).";
3593
Barry Warsaw53699e91996-12-10 23:23:01 +00003594static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003595posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003596{
3597 char *file;
3598 int mode = 0666;
3599 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003600 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003601 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003602 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003603 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003604 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003605 if (res < 0)
3606 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003607 Py_INCREF(Py_None);
3608 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003609}
3610#endif
3611
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003612
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003613#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003614static char posix_ftruncate__doc__[] =
3615"ftruncate(fd, length) -> None\n\
3616Truncate a file to a specified length.";
3617
Barry Warsaw53699e91996-12-10 23:23:01 +00003618static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003619posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003620{
3621 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003622 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003623 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003624 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003625
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003626 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003627 return NULL;
3628
3629#if !defined(HAVE_LARGEFILE_SUPPORT)
3630 length = PyInt_AsLong(lenobj);
3631#else
3632 length = PyLong_Check(lenobj) ?
3633 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3634#endif
3635 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003636 return NULL;
3637
Barry Warsaw53699e91996-12-10 23:23:01 +00003638 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003639 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003640 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003641 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003642 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003643 return NULL;
3644 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003645 Py_INCREF(Py_None);
3646 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003647}
3648#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003649
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003650#ifdef NeXT
3651#define HAVE_PUTENV
3652/* Steve Spicklemire got this putenv from NeXTAnswers */
3653static int
3654putenv(char *newval)
3655{
3656 extern char **environ;
3657
3658 static int firstTime = 1;
3659 char **ep;
3660 char *cp;
3661 int esiz;
3662 char *np;
3663
3664 if (!(np = strchr(newval, '=')))
3665 return 1;
3666 *np = '\0';
3667
3668 /* look it up */
3669 for (ep=environ ; *ep ; ep++)
3670 {
3671 /* this should always be true... */
3672 if (cp = strchr(*ep, '='))
3673 {
3674 *cp = '\0';
3675 if (!strcmp(*ep, newval))
3676 {
3677 /* got it! */
3678 *cp = '=';
3679 break;
3680 }
3681 *cp = '=';
3682 }
3683 else
3684 {
3685 *np = '=';
3686 return 1;
3687 }
3688 }
3689
3690 *np = '=';
3691 if (*ep)
3692 {
3693 /* the string was already there:
3694 just replace it with the new one */
3695 *ep = newval;
3696 return 0;
3697 }
3698
3699 /* expand environ by one */
3700 for (esiz=2, ep=environ ; *ep ; ep++)
3701 esiz++;
3702 if (firstTime)
3703 {
3704 char **epp;
3705 char **newenv;
3706 if (!(newenv = malloc(esiz * sizeof(char *))))
3707 return 1;
3708
3709 for (ep=environ, epp=newenv ; *ep ;)
3710 *epp++ = *ep++;
3711 *epp++ = newval;
3712 *epp = (char *) 0;
3713 environ = newenv;
3714 }
3715 else
3716 {
3717 if (!(environ = realloc(environ, esiz * sizeof(char *))))
3718 return 1;
3719 environ[esiz - 2] = newval;
3720 environ[esiz - 1] = (char *) 0;
3721 firstTime = 0;
3722 }
3723
3724 return 0;
3725}
Guido van Rossumc6ef2041997-08-21 02:30:45 +00003726#endif /* NeXT */
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003727
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003728
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003729#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003730static char posix_putenv__doc__[] =
3731"putenv(key, value) -> None\n\
3732Change or add an environment variable.";
3733
Fred Drake762e2061999-08-26 17:23:54 +00003734/* Save putenv() parameters as values here, so we can collect them when they
3735 * get re-set with another call for the same key. */
3736static PyObject *posix_putenv_garbage;
3737
Barry Warsaw53699e91996-12-10 23:23:01 +00003738static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003739posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003740{
3741 char *s1, *s2;
3742 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00003743 PyObject *newstr;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003744
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003745 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003746 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003747
3748#if defined(PYOS_OS2)
3749 if (stricmp(s1, "BEGINLIBPATH") == 0) {
3750 APIRET rc;
3751
3752 if (strlen(s2) == 0) /* If New Value is an Empty String */
3753 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3754
3755 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
3756 if (rc != NO_ERROR)
3757 return os2_error(rc);
3758
3759 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
3760 APIRET rc;
3761
3762 if (strlen(s2) == 0) /* If New Value is an Empty String */
3763 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3764
3765 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
3766 if (rc != NO_ERROR)
3767 return os2_error(rc);
3768 } else {
3769#endif
3770
Fred Drake762e2061999-08-26 17:23:54 +00003771 /* XXX This can leak memory -- not easy to fix :-( */
3772 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
3773 if (newstr == NULL)
3774 return PyErr_NoMemory();
3775 new = PyString_AS_STRING(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003776 (void) sprintf(new, "%s=%s", s1, s2);
3777 if (putenv(new)) {
3778 posix_error();
3779 return NULL;
3780 }
Fred Drake762e2061999-08-26 17:23:54 +00003781 /* Install the first arg and newstr in posix_putenv_garbage;
3782 * this will cause previous value to be collected. This has to
3783 * happen after the real putenv() call because the old value
3784 * was still accessible until then. */
3785 if (PyDict_SetItem(posix_putenv_garbage,
3786 PyTuple_GET_ITEM(args, 0), newstr)) {
3787 /* really not much we can do; just leak */
3788 PyErr_Clear();
3789 }
3790 else {
3791 Py_DECREF(newstr);
3792 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003793
3794#if defined(PYOS_OS2)
3795 }
3796#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003797 Py_INCREF(Py_None);
3798 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003799}
Guido van Rossumb6a47161997-09-15 22:54:34 +00003800#endif /* putenv */
3801
3802#ifdef HAVE_STRERROR
3803static char posix_strerror__doc__[] =
3804"strerror(code) -> string\n\
3805Translate an error code to a message string.";
3806
3807PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003808posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00003809{
3810 int code;
3811 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003812 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00003813 return NULL;
3814 message = strerror(code);
3815 if (message == NULL) {
3816 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00003817 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00003818 return NULL;
3819 }
3820 return PyString_FromString(message);
3821}
3822#endif /* strerror */
3823
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003824
Guido van Rossumc9641791998-08-04 15:26:23 +00003825#ifdef HAVE_SYS_WAIT_H
3826
3827#ifdef WIFSTOPPED
3828static char posix_WIFSTOPPED__doc__[] =
3829"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003830Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003831
3832static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003833posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003834{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003835#ifdef UNION_WAIT
3836 union wait status;
3837#define status_i (status.w_status)
3838#else
3839 int status;
3840#define status_i status
3841#endif
3842 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003843
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003844 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003845 {
3846 return NULL;
3847 }
3848
3849 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003850#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003851}
3852#endif /* WIFSTOPPED */
3853
3854#ifdef WIFSIGNALED
3855static char posix_WIFSIGNALED__doc__[] =
3856"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00003857Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003858
3859static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003860posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003861{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003862#ifdef UNION_WAIT
3863 union wait status;
3864#define status_i (status.w_status)
3865#else
3866 int status;
3867#define status_i status
3868#endif
3869 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003870
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003871 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003872 {
3873 return NULL;
3874 }
3875
3876 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003877#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003878}
3879#endif /* WIFSIGNALED */
3880
3881#ifdef WIFEXITED
3882static char posix_WIFEXITED__doc__[] =
3883"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003884Return true if the process returning 'status' exited using the exit()\n\
3885system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003886
3887static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003888posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003889{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003890#ifdef UNION_WAIT
3891 union wait status;
3892#define status_i (status.w_status)
3893#else
3894 int status;
3895#define status_i status
3896#endif
3897 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003898
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003899 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003900 {
3901 return NULL;
3902 }
3903
3904 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003905#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003906}
3907#endif /* WIFEXITED */
3908
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003909#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00003910static char posix_WEXITSTATUS__doc__[] =
3911"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003912Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003913
3914static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003915posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003916{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003917#ifdef UNION_WAIT
3918 union wait status;
3919#define status_i (status.w_status)
3920#else
3921 int status;
3922#define status_i status
3923#endif
3924 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003925
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003926 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003927 {
3928 return NULL;
3929 }
3930
3931 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003932#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003933}
3934#endif /* WEXITSTATUS */
3935
3936#ifdef WTERMSIG
3937static char posix_WTERMSIG__doc__[] =
3938"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003939Return the signal that terminated the process that provided the 'status'\n\
3940value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003941
3942static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003943posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003944{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003945#ifdef UNION_WAIT
3946 union wait status;
3947#define status_i (status.w_status)
3948#else
3949 int status;
3950#define status_i status
3951#endif
3952 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003953
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003954 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003955 {
3956 return NULL;
3957 }
3958
3959 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003960#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003961}
3962#endif /* WTERMSIG */
3963
3964#ifdef WSTOPSIG
3965static char posix_WSTOPSIG__doc__[] =
3966"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003967Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003968
3969static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003970posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003971{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003972#ifdef UNION_WAIT
3973 union wait status;
3974#define status_i (status.w_status)
3975#else
3976 int status;
3977#define status_i status
3978#endif
3979 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003980
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003981 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003982 {
3983 return NULL;
3984 }
3985
3986 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003987#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003988}
3989#endif /* WSTOPSIG */
3990
3991#endif /* HAVE_SYS_WAIT_H */
3992
3993
Guido van Rossum94f6f721999-01-06 18:42:14 +00003994#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00003995#ifdef _SCO_DS
3996/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
3997 needed definitions in sys/statvfs.h */
3998#define _SVID3
3999#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004000#include <sys/statvfs.h>
4001
4002static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004003"fstatvfs(fd) -> \n\
4004 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004005Perform an fstatvfs system call on the given fd.";
4006
4007static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004008posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004009{
4010 int fd, res;
4011 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004012 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004013 return NULL;
4014 Py_BEGIN_ALLOW_THREADS
4015 res = fstatvfs(fd, &st);
4016 Py_END_ALLOW_THREADS
4017 if (res != 0)
4018 return posix_error();
4019#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004020 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004021 (long) st.f_bsize,
4022 (long) st.f_frsize,
4023 (long) st.f_blocks,
4024 (long) st.f_bfree,
4025 (long) st.f_bavail,
4026 (long) st.f_files,
4027 (long) st.f_ffree,
4028 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004029 (long) st.f_flag,
4030 (long) st.f_namemax);
4031#else
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004032 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004033 (long) st.f_bsize,
4034 (long) st.f_frsize,
4035 (LONG_LONG) st.f_blocks,
4036 (LONG_LONG) st.f_bfree,
4037 (LONG_LONG) st.f_bavail,
4038 (LONG_LONG) st.f_files,
4039 (LONG_LONG) st.f_ffree,
4040 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004041 (long) st.f_flag,
4042 (long) st.f_namemax);
4043#endif
4044}
4045#endif /* HAVE_FSTATVFS */
4046
4047
4048#if defined(HAVE_STATVFS)
4049#include <sys/statvfs.h>
4050
4051static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004052"statvfs(path) -> \n\
4053 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004054Perform a statvfs system call on the given path.";
4055
4056static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004057posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004058{
4059 char *path;
4060 int res;
4061 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004062 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004063 return NULL;
4064 Py_BEGIN_ALLOW_THREADS
4065 res = statvfs(path, &st);
4066 Py_END_ALLOW_THREADS
4067 if (res != 0)
4068 return posix_error_with_filename(path);
4069#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004070 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004071 (long) st.f_bsize,
4072 (long) st.f_frsize,
4073 (long) st.f_blocks,
4074 (long) st.f_bfree,
4075 (long) st.f_bavail,
4076 (long) st.f_files,
4077 (long) st.f_ffree,
4078 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004079 (long) st.f_flag,
4080 (long) st.f_namemax);
4081#else /* HAVE_LARGEFILE_SUPPORT */
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004082 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004083 (long) st.f_bsize,
4084 (long) st.f_frsize,
4085 (LONG_LONG) st.f_blocks,
4086 (LONG_LONG) st.f_bfree,
4087 (LONG_LONG) st.f_bavail,
4088 (LONG_LONG) st.f_files,
4089 (LONG_LONG) st.f_ffree,
4090 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004091 (long) st.f_flag,
4092 (long) st.f_namemax);
4093#endif
4094}
4095#endif /* HAVE_STATVFS */
4096
4097
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004098#ifdef HAVE_TEMPNAM
4099static char posix_tempnam__doc__[] = "\
4100tempnam([dir[, prefix]]) -> string\n\
4101Return a unique name for a temporary file.\n\
4102The directory and a short may be specified as strings; they may be omitted\n\
4103or None if not needed.";
4104
4105static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004106posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004107{
4108 PyObject *result = NULL;
4109 char *dir = NULL;
4110 char *pfx = NULL;
4111 char *name;
4112
4113 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
4114 return NULL;
4115 name = tempnam(dir, pfx);
4116 if (name == NULL)
4117 return PyErr_NoMemory();
4118 result = PyString_FromString(name);
4119 free(name);
4120 return result;
4121}
Guido van Rossumd371ff11999-01-25 16:12:23 +00004122#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004123
4124
4125#ifdef HAVE_TMPFILE
4126static char posix_tmpfile__doc__[] = "\
4127tmpfile() -> file object\n\
4128Create a temporary file with no directory entries.";
4129
4130static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004131posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004132{
4133 FILE *fp;
4134
4135 if (!PyArg_ParseTuple(args, ":tmpfile"))
4136 return NULL;
4137 fp = tmpfile();
4138 if (fp == NULL)
4139 return posix_error();
4140 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
4141}
4142#endif
4143
4144
4145#ifdef HAVE_TMPNAM
4146static char posix_tmpnam__doc__[] = "\
4147tmpnam() -> string\n\
4148Return a unique name for a temporary file.";
4149
4150static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004151posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004152{
4153 char buffer[L_tmpnam];
4154 char *name;
4155
4156 if (!PyArg_ParseTuple(args, ":tmpnam"))
4157 return NULL;
Greg Wardb48bc172000-03-01 21:51:56 +00004158#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004159 name = tmpnam_r(buffer);
4160#else
4161 name = tmpnam(buffer);
4162#endif
4163 if (name == NULL) {
4164 PyErr_SetObject(PyExc_OSError,
4165 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00004166#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004167 "unexpected NULL from tmpnam_r"
4168#else
4169 "unexpected NULL from tmpnam"
4170#endif
4171 ));
4172 return NULL;
4173 }
4174 return PyString_FromString(buffer);
4175}
4176#endif
4177
4178
Fred Drakec9680921999-12-13 16:37:25 +00004179/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
4180 * It maps strings representing configuration variable names to
4181 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00004182 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00004183 * rarely-used constants. There are three separate tables that use
4184 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00004185 *
4186 * This code is always included, even if none of the interfaces that
4187 * need it are included. The #if hackery needed to avoid it would be
4188 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00004189 */
4190struct constdef {
4191 char *name;
4192 long value;
4193};
4194
Fred Drake12c6e2d1999-12-14 21:25:03 +00004195static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004196conv_confname(PyObject *arg, int *valuep, struct constdef *table,
4197 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004198{
4199 if (PyInt_Check(arg)) {
4200 *valuep = PyInt_AS_LONG(arg);
4201 return 1;
4202 }
4203 if (PyString_Check(arg)) {
4204 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00004205 size_t lo = 0;
4206 size_t mid;
4207 size_t hi = tablesize;
4208 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004209 char *confname = PyString_AS_STRING(arg);
4210 while (lo < hi) {
4211 mid = (lo + hi) / 2;
4212 cmp = strcmp(confname, table[mid].name);
4213 if (cmp < 0)
4214 hi = mid;
4215 else if (cmp > 0)
4216 lo = mid + 1;
4217 else {
4218 *valuep = table[mid].value;
4219 return 1;
4220 }
4221 }
4222 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
4223 }
4224 else
4225 PyErr_SetString(PyExc_TypeError,
4226 "configuration names must be strings or integers");
4227 return 0;
4228}
4229
4230
4231#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4232static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004233#ifdef _PC_ABI_AIO_XFER_MAX
4234 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
4235#endif
4236#ifdef _PC_ABI_ASYNC_IO
4237 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
4238#endif
Fred Drakec9680921999-12-13 16:37:25 +00004239#ifdef _PC_ASYNC_IO
4240 {"PC_ASYNC_IO", _PC_ASYNC_IO},
4241#endif
4242#ifdef _PC_CHOWN_RESTRICTED
4243 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
4244#endif
4245#ifdef _PC_FILESIZEBITS
4246 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
4247#endif
4248#ifdef _PC_LAST
4249 {"PC_LAST", _PC_LAST},
4250#endif
4251#ifdef _PC_LINK_MAX
4252 {"PC_LINK_MAX", _PC_LINK_MAX},
4253#endif
4254#ifdef _PC_MAX_CANON
4255 {"PC_MAX_CANON", _PC_MAX_CANON},
4256#endif
4257#ifdef _PC_MAX_INPUT
4258 {"PC_MAX_INPUT", _PC_MAX_INPUT},
4259#endif
4260#ifdef _PC_NAME_MAX
4261 {"PC_NAME_MAX", _PC_NAME_MAX},
4262#endif
4263#ifdef _PC_NO_TRUNC
4264 {"PC_NO_TRUNC", _PC_NO_TRUNC},
4265#endif
4266#ifdef _PC_PATH_MAX
4267 {"PC_PATH_MAX", _PC_PATH_MAX},
4268#endif
4269#ifdef _PC_PIPE_BUF
4270 {"PC_PIPE_BUF", _PC_PIPE_BUF},
4271#endif
4272#ifdef _PC_PRIO_IO
4273 {"PC_PRIO_IO", _PC_PRIO_IO},
4274#endif
4275#ifdef _PC_SOCK_MAXBUF
4276 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
4277#endif
4278#ifdef _PC_SYNC_IO
4279 {"PC_SYNC_IO", _PC_SYNC_IO},
4280#endif
4281#ifdef _PC_VDISABLE
4282 {"PC_VDISABLE", _PC_VDISABLE},
4283#endif
4284};
4285
Fred Drakec9680921999-12-13 16:37:25 +00004286static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004287conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004288{
4289 return conv_confname(arg, valuep, posix_constants_pathconf,
4290 sizeof(posix_constants_pathconf)
4291 / sizeof(struct constdef));
4292}
4293#endif
4294
4295#ifdef HAVE_FPATHCONF
4296static char posix_fpathconf__doc__[] = "\
4297fpathconf(fd, name) -> integer\n\
4298Return the configuration limit name for the file descriptor fd.\n\
4299If there is no limit, return -1.";
4300
4301static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004302posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004303{
4304 PyObject *result = NULL;
4305 int name, fd;
4306
Fred Drake12c6e2d1999-12-14 21:25:03 +00004307 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4308 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00004309 long limit;
4310
4311 errno = 0;
4312 limit = fpathconf(fd, name);
4313 if (limit == -1 && errno != 0)
4314 posix_error();
4315 else
4316 result = PyInt_FromLong(limit);
4317 }
4318 return result;
4319}
4320#endif
4321
4322
4323#ifdef HAVE_PATHCONF
4324static char posix_pathconf__doc__[] = "\
4325pathconf(path, name) -> integer\n\
4326Return the configuration limit name for the file or directory path.\n\
4327If there is no limit, return -1.";
4328
4329static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004330posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004331{
4332 PyObject *result = NULL;
4333 int name;
4334 char *path;
4335
4336 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4337 conv_path_confname, &name)) {
4338 long limit;
4339
4340 errno = 0;
4341 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004342 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00004343 if (errno == EINVAL)
4344 /* could be a path or name problem */
4345 posix_error();
4346 else
4347 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004348 }
Fred Drakec9680921999-12-13 16:37:25 +00004349 else
4350 result = PyInt_FromLong(limit);
4351 }
4352 return result;
4353}
4354#endif
4355
4356#ifdef HAVE_CONFSTR
4357static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004358#ifdef _CS_ARCHITECTURE
4359 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4360#endif
4361#ifdef _CS_HOSTNAME
4362 {"CS_HOSTNAME", _CS_HOSTNAME},
4363#endif
4364#ifdef _CS_HW_PROVIDER
4365 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4366#endif
4367#ifdef _CS_HW_SERIAL
4368 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4369#endif
4370#ifdef _CS_INITTAB_NAME
4371 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4372#endif
Fred Drakec9680921999-12-13 16:37:25 +00004373#ifdef _CS_LFS64_CFLAGS
4374 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4375#endif
4376#ifdef _CS_LFS64_LDFLAGS
4377 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4378#endif
4379#ifdef _CS_LFS64_LIBS
4380 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4381#endif
4382#ifdef _CS_LFS64_LINTFLAGS
4383 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4384#endif
4385#ifdef _CS_LFS_CFLAGS
4386 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4387#endif
4388#ifdef _CS_LFS_LDFLAGS
4389 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4390#endif
4391#ifdef _CS_LFS_LIBS
4392 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4393#endif
4394#ifdef _CS_LFS_LINTFLAGS
4395 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4396#endif
Fred Draked86ed291999-12-15 15:34:33 +00004397#ifdef _CS_MACHINE
4398 {"CS_MACHINE", _CS_MACHINE},
4399#endif
Fred Drakec9680921999-12-13 16:37:25 +00004400#ifdef _CS_PATH
4401 {"CS_PATH", _CS_PATH},
4402#endif
Fred Draked86ed291999-12-15 15:34:33 +00004403#ifdef _CS_RELEASE
4404 {"CS_RELEASE", _CS_RELEASE},
4405#endif
4406#ifdef _CS_SRPC_DOMAIN
4407 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4408#endif
4409#ifdef _CS_SYSNAME
4410 {"CS_SYSNAME", _CS_SYSNAME},
4411#endif
4412#ifdef _CS_VERSION
4413 {"CS_VERSION", _CS_VERSION},
4414#endif
Fred Drakec9680921999-12-13 16:37:25 +00004415#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4416 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4417#endif
4418#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4419 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4420#endif
4421#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4422 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4423#endif
4424#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4425 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4426#endif
4427#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4428 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4429#endif
4430#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4431 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4432#endif
4433#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4434 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4435#endif
4436#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4437 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4438#endif
4439#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4440 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4441#endif
4442#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4443 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4444#endif
4445#ifdef _CS_XBS5_LP64_OFF64_LIBS
4446 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4447#endif
4448#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4449 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4450#endif
4451#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4452 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4453#endif
4454#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4455 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4456#endif
4457#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4458 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4459#endif
4460#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4461 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4462#endif
Fred Draked86ed291999-12-15 15:34:33 +00004463#ifdef _MIPS_CS_AVAIL_PROCESSORS
4464 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4465#endif
4466#ifdef _MIPS_CS_BASE
4467 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4468#endif
4469#ifdef _MIPS_CS_HOSTID
4470 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4471#endif
4472#ifdef _MIPS_CS_HW_NAME
4473 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4474#endif
4475#ifdef _MIPS_CS_NUM_PROCESSORS
4476 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4477#endif
4478#ifdef _MIPS_CS_OSREL_MAJ
4479 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4480#endif
4481#ifdef _MIPS_CS_OSREL_MIN
4482 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4483#endif
4484#ifdef _MIPS_CS_OSREL_PATCH
4485 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4486#endif
4487#ifdef _MIPS_CS_OS_NAME
4488 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4489#endif
4490#ifdef _MIPS_CS_OS_PROVIDER
4491 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4492#endif
4493#ifdef _MIPS_CS_PROCESSORS
4494 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4495#endif
4496#ifdef _MIPS_CS_SERIAL
4497 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4498#endif
4499#ifdef _MIPS_CS_VENDOR
4500 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4501#endif
Fred Drakec9680921999-12-13 16:37:25 +00004502};
4503
4504static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004505conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004506{
4507 return conv_confname(arg, valuep, posix_constants_confstr,
4508 sizeof(posix_constants_confstr)
4509 / sizeof(struct constdef));
4510}
4511
4512static char posix_confstr__doc__[] = "\
4513confstr(name) -> string\n\
4514Return a string-valued system configuration variable.";
4515
4516static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004517posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004518{
4519 PyObject *result = NULL;
4520 int name;
4521 char buffer[64];
4522
4523 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4524 int len = confstr(name, buffer, sizeof(buffer));
4525
Fred Drakec9680921999-12-13 16:37:25 +00004526 errno = 0;
4527 if (len == 0) {
4528 if (errno != 0)
4529 posix_error();
4530 else
4531 result = PyString_FromString("");
4532 }
4533 else {
4534 if (len >= sizeof(buffer)) {
4535 result = PyString_FromStringAndSize(NULL, len);
4536 if (result != NULL)
4537 confstr(name, PyString_AS_STRING(result), len+1);
4538 }
4539 else
4540 result = PyString_FromString(buffer);
4541 }
4542 }
4543 return result;
4544}
4545#endif
4546
4547
4548#ifdef HAVE_SYSCONF
4549static struct constdef posix_constants_sysconf[] = {
4550#ifdef _SC_2_CHAR_TERM
4551 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4552#endif
4553#ifdef _SC_2_C_BIND
4554 {"SC_2_C_BIND", _SC_2_C_BIND},
4555#endif
4556#ifdef _SC_2_C_DEV
4557 {"SC_2_C_DEV", _SC_2_C_DEV},
4558#endif
4559#ifdef _SC_2_C_VERSION
4560 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4561#endif
4562#ifdef _SC_2_FORT_DEV
4563 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4564#endif
4565#ifdef _SC_2_FORT_RUN
4566 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4567#endif
4568#ifdef _SC_2_LOCALEDEF
4569 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4570#endif
4571#ifdef _SC_2_SW_DEV
4572 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4573#endif
4574#ifdef _SC_2_UPE
4575 {"SC_2_UPE", _SC_2_UPE},
4576#endif
4577#ifdef _SC_2_VERSION
4578 {"SC_2_VERSION", _SC_2_VERSION},
4579#endif
Fred Draked86ed291999-12-15 15:34:33 +00004580#ifdef _SC_ABI_ASYNCHRONOUS_IO
4581 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4582#endif
4583#ifdef _SC_ACL
4584 {"SC_ACL", _SC_ACL},
4585#endif
Fred Drakec9680921999-12-13 16:37:25 +00004586#ifdef _SC_AIO_LISTIO_MAX
4587 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4588#endif
Fred Drakec9680921999-12-13 16:37:25 +00004589#ifdef _SC_AIO_MAX
4590 {"SC_AIO_MAX", _SC_AIO_MAX},
4591#endif
4592#ifdef _SC_AIO_PRIO_DELTA_MAX
4593 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4594#endif
4595#ifdef _SC_ARG_MAX
4596 {"SC_ARG_MAX", _SC_ARG_MAX},
4597#endif
4598#ifdef _SC_ASYNCHRONOUS_IO
4599 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4600#endif
4601#ifdef _SC_ATEXIT_MAX
4602 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4603#endif
Fred Draked86ed291999-12-15 15:34:33 +00004604#ifdef _SC_AUDIT
4605 {"SC_AUDIT", _SC_AUDIT},
4606#endif
Fred Drakec9680921999-12-13 16:37:25 +00004607#ifdef _SC_AVPHYS_PAGES
4608 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4609#endif
4610#ifdef _SC_BC_BASE_MAX
4611 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4612#endif
4613#ifdef _SC_BC_DIM_MAX
4614 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4615#endif
4616#ifdef _SC_BC_SCALE_MAX
4617 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4618#endif
4619#ifdef _SC_BC_STRING_MAX
4620 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4621#endif
Fred Draked86ed291999-12-15 15:34:33 +00004622#ifdef _SC_CAP
4623 {"SC_CAP", _SC_CAP},
4624#endif
Fred Drakec9680921999-12-13 16:37:25 +00004625#ifdef _SC_CHARCLASS_NAME_MAX
4626 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4627#endif
4628#ifdef _SC_CHAR_BIT
4629 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4630#endif
4631#ifdef _SC_CHAR_MAX
4632 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4633#endif
4634#ifdef _SC_CHAR_MIN
4635 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4636#endif
4637#ifdef _SC_CHILD_MAX
4638 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4639#endif
4640#ifdef _SC_CLK_TCK
4641 {"SC_CLK_TCK", _SC_CLK_TCK},
4642#endif
4643#ifdef _SC_COHER_BLKSZ
4644 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4645#endif
4646#ifdef _SC_COLL_WEIGHTS_MAX
4647 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4648#endif
4649#ifdef _SC_DCACHE_ASSOC
4650 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4651#endif
4652#ifdef _SC_DCACHE_BLKSZ
4653 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4654#endif
4655#ifdef _SC_DCACHE_LINESZ
4656 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4657#endif
4658#ifdef _SC_DCACHE_SZ
4659 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
4660#endif
4661#ifdef _SC_DCACHE_TBLKSZ
4662 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
4663#endif
4664#ifdef _SC_DELAYTIMER_MAX
4665 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
4666#endif
4667#ifdef _SC_EQUIV_CLASS_MAX
4668 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
4669#endif
4670#ifdef _SC_EXPR_NEST_MAX
4671 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
4672#endif
4673#ifdef _SC_FSYNC
4674 {"SC_FSYNC", _SC_FSYNC},
4675#endif
4676#ifdef _SC_GETGR_R_SIZE_MAX
4677 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
4678#endif
4679#ifdef _SC_GETPW_R_SIZE_MAX
4680 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
4681#endif
4682#ifdef _SC_ICACHE_ASSOC
4683 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
4684#endif
4685#ifdef _SC_ICACHE_BLKSZ
4686 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
4687#endif
4688#ifdef _SC_ICACHE_LINESZ
4689 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
4690#endif
4691#ifdef _SC_ICACHE_SZ
4692 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
4693#endif
Fred Draked86ed291999-12-15 15:34:33 +00004694#ifdef _SC_INF
4695 {"SC_INF", _SC_INF},
4696#endif
Fred Drakec9680921999-12-13 16:37:25 +00004697#ifdef _SC_INT_MAX
4698 {"SC_INT_MAX", _SC_INT_MAX},
4699#endif
4700#ifdef _SC_INT_MIN
4701 {"SC_INT_MIN", _SC_INT_MIN},
4702#endif
4703#ifdef _SC_IOV_MAX
4704 {"SC_IOV_MAX", _SC_IOV_MAX},
4705#endif
Fred Draked86ed291999-12-15 15:34:33 +00004706#ifdef _SC_IP_SECOPTS
4707 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
4708#endif
Fred Drakec9680921999-12-13 16:37:25 +00004709#ifdef _SC_JOB_CONTROL
4710 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
4711#endif
Fred Draked86ed291999-12-15 15:34:33 +00004712#ifdef _SC_KERN_POINTERS
4713 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
4714#endif
4715#ifdef _SC_KERN_SIM
4716 {"SC_KERN_SIM", _SC_KERN_SIM},
4717#endif
Fred Drakec9680921999-12-13 16:37:25 +00004718#ifdef _SC_LINE_MAX
4719 {"SC_LINE_MAX", _SC_LINE_MAX},
4720#endif
4721#ifdef _SC_LOGIN_NAME_MAX
4722 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
4723#endif
4724#ifdef _SC_LOGNAME_MAX
4725 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
4726#endif
4727#ifdef _SC_LONG_BIT
4728 {"SC_LONG_BIT", _SC_LONG_BIT},
4729#endif
Fred Draked86ed291999-12-15 15:34:33 +00004730#ifdef _SC_MAC
4731 {"SC_MAC", _SC_MAC},
4732#endif
Fred Drakec9680921999-12-13 16:37:25 +00004733#ifdef _SC_MAPPED_FILES
4734 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
4735#endif
4736#ifdef _SC_MAXPID
4737 {"SC_MAXPID", _SC_MAXPID},
4738#endif
4739#ifdef _SC_MB_LEN_MAX
4740 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
4741#endif
4742#ifdef _SC_MEMLOCK
4743 {"SC_MEMLOCK", _SC_MEMLOCK},
4744#endif
4745#ifdef _SC_MEMLOCK_RANGE
4746 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
4747#endif
4748#ifdef _SC_MEMORY_PROTECTION
4749 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
4750#endif
4751#ifdef _SC_MESSAGE_PASSING
4752 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
4753#endif
Fred Draked86ed291999-12-15 15:34:33 +00004754#ifdef _SC_MMAP_FIXED_ALIGNMENT
4755 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
4756#endif
Fred Drakec9680921999-12-13 16:37:25 +00004757#ifdef _SC_MQ_OPEN_MAX
4758 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
4759#endif
4760#ifdef _SC_MQ_PRIO_MAX
4761 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
4762#endif
Fred Draked86ed291999-12-15 15:34:33 +00004763#ifdef _SC_NACLS_MAX
4764 {"SC_NACLS_MAX", _SC_NACLS_MAX},
4765#endif
Fred Drakec9680921999-12-13 16:37:25 +00004766#ifdef _SC_NGROUPS_MAX
4767 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
4768#endif
4769#ifdef _SC_NL_ARGMAX
4770 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
4771#endif
4772#ifdef _SC_NL_LANGMAX
4773 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
4774#endif
4775#ifdef _SC_NL_MSGMAX
4776 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
4777#endif
4778#ifdef _SC_NL_NMAX
4779 {"SC_NL_NMAX", _SC_NL_NMAX},
4780#endif
4781#ifdef _SC_NL_SETMAX
4782 {"SC_NL_SETMAX", _SC_NL_SETMAX},
4783#endif
4784#ifdef _SC_NL_TEXTMAX
4785 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
4786#endif
4787#ifdef _SC_NPROCESSORS_CONF
4788 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
4789#endif
4790#ifdef _SC_NPROCESSORS_ONLN
4791 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
4792#endif
Fred Draked86ed291999-12-15 15:34:33 +00004793#ifdef _SC_NPROC_CONF
4794 {"SC_NPROC_CONF", _SC_NPROC_CONF},
4795#endif
4796#ifdef _SC_NPROC_ONLN
4797 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
4798#endif
Fred Drakec9680921999-12-13 16:37:25 +00004799#ifdef _SC_NZERO
4800 {"SC_NZERO", _SC_NZERO},
4801#endif
4802#ifdef _SC_OPEN_MAX
4803 {"SC_OPEN_MAX", _SC_OPEN_MAX},
4804#endif
4805#ifdef _SC_PAGESIZE
4806 {"SC_PAGESIZE", _SC_PAGESIZE},
4807#endif
4808#ifdef _SC_PAGE_SIZE
4809 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
4810#endif
4811#ifdef _SC_PASS_MAX
4812 {"SC_PASS_MAX", _SC_PASS_MAX},
4813#endif
4814#ifdef _SC_PHYS_PAGES
4815 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
4816#endif
4817#ifdef _SC_PII
4818 {"SC_PII", _SC_PII},
4819#endif
4820#ifdef _SC_PII_INTERNET
4821 {"SC_PII_INTERNET", _SC_PII_INTERNET},
4822#endif
4823#ifdef _SC_PII_INTERNET_DGRAM
4824 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
4825#endif
4826#ifdef _SC_PII_INTERNET_STREAM
4827 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
4828#endif
4829#ifdef _SC_PII_OSI
4830 {"SC_PII_OSI", _SC_PII_OSI},
4831#endif
4832#ifdef _SC_PII_OSI_CLTS
4833 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
4834#endif
4835#ifdef _SC_PII_OSI_COTS
4836 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
4837#endif
4838#ifdef _SC_PII_OSI_M
4839 {"SC_PII_OSI_M", _SC_PII_OSI_M},
4840#endif
4841#ifdef _SC_PII_SOCKET
4842 {"SC_PII_SOCKET", _SC_PII_SOCKET},
4843#endif
4844#ifdef _SC_PII_XTI
4845 {"SC_PII_XTI", _SC_PII_XTI},
4846#endif
4847#ifdef _SC_POLL
4848 {"SC_POLL", _SC_POLL},
4849#endif
4850#ifdef _SC_PRIORITIZED_IO
4851 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
4852#endif
4853#ifdef _SC_PRIORITY_SCHEDULING
4854 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
4855#endif
4856#ifdef _SC_REALTIME_SIGNALS
4857 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
4858#endif
4859#ifdef _SC_RE_DUP_MAX
4860 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
4861#endif
4862#ifdef _SC_RTSIG_MAX
4863 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
4864#endif
4865#ifdef _SC_SAVED_IDS
4866 {"SC_SAVED_IDS", _SC_SAVED_IDS},
4867#endif
4868#ifdef _SC_SCHAR_MAX
4869 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
4870#endif
4871#ifdef _SC_SCHAR_MIN
4872 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
4873#endif
4874#ifdef _SC_SELECT
4875 {"SC_SELECT", _SC_SELECT},
4876#endif
4877#ifdef _SC_SEMAPHORES
4878 {"SC_SEMAPHORES", _SC_SEMAPHORES},
4879#endif
4880#ifdef _SC_SEM_NSEMS_MAX
4881 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
4882#endif
4883#ifdef _SC_SEM_VALUE_MAX
4884 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
4885#endif
4886#ifdef _SC_SHARED_MEMORY_OBJECTS
4887 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
4888#endif
4889#ifdef _SC_SHRT_MAX
4890 {"SC_SHRT_MAX", _SC_SHRT_MAX},
4891#endif
4892#ifdef _SC_SHRT_MIN
4893 {"SC_SHRT_MIN", _SC_SHRT_MIN},
4894#endif
4895#ifdef _SC_SIGQUEUE_MAX
4896 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
4897#endif
4898#ifdef _SC_SIGRT_MAX
4899 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
4900#endif
4901#ifdef _SC_SIGRT_MIN
4902 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
4903#endif
Fred Draked86ed291999-12-15 15:34:33 +00004904#ifdef _SC_SOFTPOWER
4905 {"SC_SOFTPOWER", _SC_SOFTPOWER},
4906#endif
Fred Drakec9680921999-12-13 16:37:25 +00004907#ifdef _SC_SPLIT_CACHE
4908 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
4909#endif
4910#ifdef _SC_SSIZE_MAX
4911 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
4912#endif
4913#ifdef _SC_STACK_PROT
4914 {"SC_STACK_PROT", _SC_STACK_PROT},
4915#endif
4916#ifdef _SC_STREAM_MAX
4917 {"SC_STREAM_MAX", _SC_STREAM_MAX},
4918#endif
4919#ifdef _SC_SYNCHRONIZED_IO
4920 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
4921#endif
4922#ifdef _SC_THREADS
4923 {"SC_THREADS", _SC_THREADS},
4924#endif
4925#ifdef _SC_THREAD_ATTR_STACKADDR
4926 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
4927#endif
4928#ifdef _SC_THREAD_ATTR_STACKSIZE
4929 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
4930#endif
4931#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
4932 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
4933#endif
4934#ifdef _SC_THREAD_KEYS_MAX
4935 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
4936#endif
4937#ifdef _SC_THREAD_PRIORITY_SCHEDULING
4938 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
4939#endif
4940#ifdef _SC_THREAD_PRIO_INHERIT
4941 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
4942#endif
4943#ifdef _SC_THREAD_PRIO_PROTECT
4944 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
4945#endif
4946#ifdef _SC_THREAD_PROCESS_SHARED
4947 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
4948#endif
4949#ifdef _SC_THREAD_SAFE_FUNCTIONS
4950 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
4951#endif
4952#ifdef _SC_THREAD_STACK_MIN
4953 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
4954#endif
4955#ifdef _SC_THREAD_THREADS_MAX
4956 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
4957#endif
4958#ifdef _SC_TIMERS
4959 {"SC_TIMERS", _SC_TIMERS},
4960#endif
4961#ifdef _SC_TIMER_MAX
4962 {"SC_TIMER_MAX", _SC_TIMER_MAX},
4963#endif
4964#ifdef _SC_TTY_NAME_MAX
4965 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
4966#endif
4967#ifdef _SC_TZNAME_MAX
4968 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
4969#endif
4970#ifdef _SC_T_IOV_MAX
4971 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
4972#endif
4973#ifdef _SC_UCHAR_MAX
4974 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
4975#endif
4976#ifdef _SC_UINT_MAX
4977 {"SC_UINT_MAX", _SC_UINT_MAX},
4978#endif
4979#ifdef _SC_UIO_MAXIOV
4980 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
4981#endif
4982#ifdef _SC_ULONG_MAX
4983 {"SC_ULONG_MAX", _SC_ULONG_MAX},
4984#endif
4985#ifdef _SC_USHRT_MAX
4986 {"SC_USHRT_MAX", _SC_USHRT_MAX},
4987#endif
4988#ifdef _SC_VERSION
4989 {"SC_VERSION", _SC_VERSION},
4990#endif
4991#ifdef _SC_WORD_BIT
4992 {"SC_WORD_BIT", _SC_WORD_BIT},
4993#endif
4994#ifdef _SC_XBS5_ILP32_OFF32
4995 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
4996#endif
4997#ifdef _SC_XBS5_ILP32_OFFBIG
4998 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
4999#endif
5000#ifdef _SC_XBS5_LP64_OFF64
5001 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
5002#endif
5003#ifdef _SC_XBS5_LPBIG_OFFBIG
5004 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
5005#endif
5006#ifdef _SC_XOPEN_CRYPT
5007 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
5008#endif
5009#ifdef _SC_XOPEN_ENH_I18N
5010 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
5011#endif
5012#ifdef _SC_XOPEN_LEGACY
5013 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
5014#endif
5015#ifdef _SC_XOPEN_REALTIME
5016 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
5017#endif
5018#ifdef _SC_XOPEN_REALTIME_THREADS
5019 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
5020#endif
5021#ifdef _SC_XOPEN_SHM
5022 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
5023#endif
5024#ifdef _SC_XOPEN_UNIX
5025 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
5026#endif
5027#ifdef _SC_XOPEN_VERSION
5028 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
5029#endif
5030#ifdef _SC_XOPEN_XCU_VERSION
5031 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
5032#endif
5033#ifdef _SC_XOPEN_XPG2
5034 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
5035#endif
5036#ifdef _SC_XOPEN_XPG3
5037 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
5038#endif
5039#ifdef _SC_XOPEN_XPG4
5040 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
5041#endif
5042};
5043
5044static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005045conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005046{
5047 return conv_confname(arg, valuep, posix_constants_sysconf,
5048 sizeof(posix_constants_sysconf)
5049 / sizeof(struct constdef));
5050}
5051
5052static char posix_sysconf__doc__[] = "\
5053sysconf(name) -> integer\n\
5054Return an integer-valued system configuration variable.";
5055
5056static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005057posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005058{
5059 PyObject *result = NULL;
5060 int name;
5061
5062 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
5063 int value;
5064
5065 errno = 0;
5066 value = sysconf(name);
5067 if (value == -1 && errno != 0)
5068 posix_error();
5069 else
5070 result = PyInt_FromLong(value);
5071 }
5072 return result;
5073}
5074#endif
5075
5076
Fred Drakebec628d1999-12-15 18:31:10 +00005077/* This code is used to ensure that the tables of configuration value names
5078 * are in sorted order as required by conv_confname(), and also to build the
5079 * the exported dictionaries that are used to publish information about the
5080 * names available on the host platform.
5081 *
5082 * Sorting the table at runtime ensures that the table is properly ordered
5083 * when used, even for platforms we're not able to test on. It also makes
5084 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00005085 */
Fred Drakebec628d1999-12-15 18:31:10 +00005086
5087static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005088cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00005089{
5090 const struct constdef *c1 =
5091 (const struct constdef *) v1;
5092 const struct constdef *c2 =
5093 (const struct constdef *) v2;
5094
5095 return strcmp(c1->name, c2->name);
5096}
5097
5098static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005099setup_confname_table(struct constdef *table, size_t tablesize,
5100 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005101{
Fred Drakebec628d1999-12-15 18:31:10 +00005102 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00005103 size_t i;
5104 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00005105
5106 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
5107 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00005108 if (d == NULL)
5109 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005110
Barry Warsaw3155db32000-04-13 15:20:40 +00005111 for (i=0; i < tablesize; ++i) {
5112 PyObject *o = PyInt_FromLong(table[i].value);
5113 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
5114 Py_XDECREF(o);
5115 Py_DECREF(d);
5116 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005117 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005118 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00005119 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005120 status = PyDict_SetItemString(moddict, tablename, d);
5121 Py_DECREF(d);
5122 return status;
Fred Draked86ed291999-12-15 15:34:33 +00005123}
5124
Fred Drakebec628d1999-12-15 18:31:10 +00005125/* Return -1 on failure, 0 on success. */
5126static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005127setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005128{
5129#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00005130 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00005131 sizeof(posix_constants_pathconf)
5132 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005133 "pathconf_names", moddict))
5134 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005135#endif
5136#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00005137 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00005138 sizeof(posix_constants_confstr)
5139 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005140 "confstr_names", moddict))
5141 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005142#endif
5143#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00005144 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00005145 sizeof(posix_constants_sysconf)
5146 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005147 "sysconf_names", moddict))
5148 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005149#endif
Fred Drakebec628d1999-12-15 18:31:10 +00005150 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00005151}
Fred Draked86ed291999-12-15 15:34:33 +00005152
5153
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005154static char posix_abort__doc__[] = "\
5155abort() -> does not return!\n\
5156Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
5157in the hardest way possible on the hosting operating system.";
5158
5159static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005160posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005161{
5162 if (!PyArg_ParseTuple(args, ":abort"))
5163 return NULL;
5164 abort();
5165 /*NOTREACHED*/
5166 Py_FatalError("abort() called from Python code didn't abort!");
5167 return NULL;
5168}
Fred Drakebec628d1999-12-15 18:31:10 +00005169
Tim Petersf58a7aa2000-09-22 10:05:54 +00005170#ifdef MS_WIN32
5171static char win32_startfile__doc__[] = "\
5172startfile(filepath) - Start a file with its associated application.\n\
5173\n\
5174This acts like double-clicking the file in Explorer, or giving the file\n\
5175name as an argument to the DOS \"start\" command: the file is opened\n\
5176with whatever application (if any) its extension is associated.\n\
5177\n\
5178startfile returns as soon as the associated application is launched.\n\
5179There is no option to wait for the application to close, and no way\n\
5180to retrieve the application's exit status.\n\
5181\n\
5182The filepath is relative to the current directory. If you want to use\n\
5183an absolute path, make sure the first character is not a slash (\"/\");\n\
5184the underlying Win32 ShellExecute function doesn't work if it is.";
5185
5186static PyObject *
5187win32_startfile(PyObject *self, PyObject *args)
5188{
5189 char *filepath;
5190 HINSTANCE rc;
5191 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
5192 return NULL;
5193 Py_BEGIN_ALLOW_THREADS
5194 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
5195 Py_END_ALLOW_THREADS
5196 if (rc <= (HINSTANCE)32)
5197 return win32_error("startfile", filepath);
5198 Py_INCREF(Py_None);
5199 return Py_None;
5200}
5201#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005202
5203static PyMethodDef posix_methods[] = {
5204 {"access", posix_access, METH_VARARGS, posix_access__doc__},
5205#ifdef HAVE_TTYNAME
5206 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
5207#endif
5208 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
5209 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005210#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005211 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005212#endif /* HAVE_CHOWN */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005213#ifdef HAVE_CTERMID
5214 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
5215#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00005216#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005217 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00005218#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005219#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005220 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005221#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005222 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
5223 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
5224 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005225#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005226 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005227#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005228#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005229 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005230#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005231 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
5232 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
5233 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005234#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005235 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005236#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005237#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005238 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005239#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005240 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005241#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005242 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005243#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005244 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
5245 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
5246 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005247#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005248 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005249#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005250 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005251#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005252 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5253 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005254#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00005255#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005256 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5257 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00005258#endif /* HAVE_SPAWNV */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005259#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005260 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005261#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005262#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005263 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00005264#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005265#ifdef HAVE_FORKPTY
5266 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5267#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005268#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005269 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005270#endif /* HAVE_GETEGID */
5271#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005272 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005273#endif /* HAVE_GETEUID */
5274#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005275 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005276#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00005277#ifdef HAVE_GETGROUPS
5278 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5279#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005280 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005281#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005282 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005283#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005284#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005285 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005286#endif /* HAVE_GETPPID */
5287#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005288 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005289#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005290#ifdef HAVE_GETLOGIN
5291 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5292#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00005293#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005294 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005295#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00005296#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005297 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00005298#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005299#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005300 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005301#ifdef MS_WIN32
5302 {"popen2", win32_popen2, METH_VARARGS},
5303 {"popen3", win32_popen3, METH_VARARGS},
5304 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00005305 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005306#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005307#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005308#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005309 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005310#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005311#ifdef HAVE_SETEUID
5312 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5313#endif /* HAVE_SETEUID */
5314#ifdef HAVE_SETEGID
5315 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5316#endif /* HAVE_SETEGID */
5317#ifdef HAVE_SETREUID
5318 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5319#endif /* HAVE_SETREUID */
5320#ifdef HAVE_SETREGID
5321 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5322#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005323#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005324 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005325#endif /* HAVE_SETGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005326#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005327 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005328#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005329#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005330 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005331#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005332#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005333 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005334#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005335#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005336 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005337#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005338#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005339 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005340#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005341#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005342 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005343#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005344#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005345 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005346#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005347 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5348 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5349 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5350 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5351 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5352 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5353 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5354 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5355 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00005356 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005357#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005358 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005359#endif
5360#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005361 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005362#endif
5363#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005364 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005365#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005366#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005367 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005368#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00005369#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005370 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00005371#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00005372#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005373 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005374#endif
5375#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005376 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005377#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00005378#ifdef HAVE_SYS_WAIT_H
5379#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005380 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005381#endif /* WIFSTOPPED */
5382#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005383 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005384#endif /* WIFSIGNALED */
5385#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005386 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005387#endif /* WIFEXITED */
5388#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005389 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005390#endif /* WEXITSTATUS */
5391#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005392 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005393#endif /* WTERMSIG */
5394#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005395 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005396#endif /* WSTOPSIG */
5397#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005398#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005399 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005400#endif
5401#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005402 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005403#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00005404#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005405 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5406#endif
5407#ifdef HAVE_TEMPNAM
5408 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5409#endif
5410#ifdef HAVE_TMPNAM
5411 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5412#endif
Fred Drakec9680921999-12-13 16:37:25 +00005413#ifdef HAVE_CONFSTR
5414 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5415#endif
5416#ifdef HAVE_SYSCONF
5417 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5418#endif
5419#ifdef HAVE_FPATHCONF
5420 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5421#endif
5422#ifdef HAVE_PATHCONF
5423 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5424#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005425 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005426 {NULL, NULL} /* Sentinel */
5427};
5428
5429
Barry Warsaw4a342091996-12-19 23:50:02 +00005430static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005431ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005432{
5433 PyObject* v = PyInt_FromLong(value);
5434 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5435 return -1; /* triggers fatal error */
5436
5437 Py_DECREF(v);
5438 return 0;
5439}
5440
Guido van Rossumd48f2521997-12-05 22:19:34 +00005441#if defined(PYOS_OS2)
5442/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5443static int insertvalues(PyObject *d)
5444{
5445 APIRET rc;
5446 ULONG values[QSV_MAX+1];
5447 PyObject *v;
5448 char *ver, tmp[10];
5449
5450 Py_BEGIN_ALLOW_THREADS
5451 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5452 Py_END_ALLOW_THREADS
5453
5454 if (rc != NO_ERROR) {
5455 os2_error(rc);
5456 return -1;
5457 }
5458
5459 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5460 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5461 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5462 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5463 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5464 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5465 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5466
5467 switch (values[QSV_VERSION_MINOR]) {
5468 case 0: ver = "2.00"; break;
5469 case 10: ver = "2.10"; break;
5470 case 11: ver = "2.11"; break;
5471 case 30: ver = "3.00"; break;
5472 case 40: ver = "4.00"; break;
5473 case 50: ver = "5.00"; break;
5474 default:
5475 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
5476 values[QSV_VERSION_MINOR]);
5477 ver = &tmp[0];
5478 }
5479
5480 /* Add Indicator of the Version of the Operating System */
5481 v = PyString_FromString(ver);
5482 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5483 return -1;
5484 Py_DECREF(v);
5485
5486 /* Add Indicator of Which Drive was Used to Boot the System */
5487 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5488 tmp[1] = ':';
5489 tmp[2] = '\0';
5490
5491 v = PyString_FromString(tmp);
5492 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5493 return -1;
5494 Py_DECREF(v);
5495
5496 return 0;
5497}
5498#endif
5499
Barry Warsaw4a342091996-12-19 23:50:02 +00005500static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005501all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00005502{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005503#ifdef F_OK
5504 if (ins(d, "F_OK", (long)F_OK)) return -1;
5505#endif
5506#ifdef R_OK
5507 if (ins(d, "R_OK", (long)R_OK)) return -1;
5508#endif
5509#ifdef W_OK
5510 if (ins(d, "W_OK", (long)W_OK)) return -1;
5511#endif
5512#ifdef X_OK
5513 if (ins(d, "X_OK", (long)X_OK)) return -1;
5514#endif
Fred Drakec9680921999-12-13 16:37:25 +00005515#ifdef NGROUPS_MAX
5516 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5517#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005518#ifdef TMP_MAX
5519 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5520#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005521#ifdef WNOHANG
5522 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5523#endif
5524#ifdef O_RDONLY
5525 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5526#endif
5527#ifdef O_WRONLY
5528 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5529#endif
5530#ifdef O_RDWR
5531 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5532#endif
5533#ifdef O_NDELAY
5534 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5535#endif
5536#ifdef O_NONBLOCK
5537 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5538#endif
5539#ifdef O_APPEND
5540 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5541#endif
5542#ifdef O_DSYNC
5543 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5544#endif
5545#ifdef O_RSYNC
5546 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5547#endif
5548#ifdef O_SYNC
5549 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5550#endif
5551#ifdef O_NOCTTY
5552 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5553#endif
5554#ifdef O_CREAT
5555 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5556#endif
5557#ifdef O_EXCL
5558 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5559#endif
5560#ifdef O_TRUNC
5561 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5562#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005563#ifdef O_BINARY
5564 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5565#endif
5566#ifdef O_TEXT
5567 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5568#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005569
Guido van Rossum246bc171999-02-01 23:54:31 +00005570#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005571 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5572 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5573 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5574 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5575 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005576#endif
5577
Guido van Rossumd48f2521997-12-05 22:19:34 +00005578#if defined(PYOS_OS2)
5579 if (insertvalues(d)) return -1;
5580#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005581 return 0;
5582}
5583
5584
Guido van Rossumc5a0f531997-12-02 20:36:02 +00005585#if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005586#define INITFUNC initnt
5587#define MODNAME "nt"
5588#else
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005589#if defined(PYOS_OS2)
5590#define INITFUNC initos2
5591#define MODNAME "os2"
5592#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005593#define INITFUNC initposix
5594#define MODNAME "posix"
5595#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005596#endif
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005597
Guido van Rossum3886bb61998-12-04 18:50:17 +00005598DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005599INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00005600{
Barry Warsaw53699e91996-12-10 23:23:01 +00005601 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005602
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005603 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005604 posix_methods,
5605 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005606 (PyObject *)NULL,
5607 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005608 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005609
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005610 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005611 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005612 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005613 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005614 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005615
Barry Warsaw4a342091996-12-19 23:50:02 +00005616 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005617 return;
5618
Fred Drakebec628d1999-12-15 18:31:10 +00005619 if (setup_confname_tables(d))
5620 return;
5621
Barry Warsawca74da41999-02-09 19:31:45 +00005622 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005623
Guido van Rossumb3d39562000-01-31 18:41:26 +00005624#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00005625 if (posix_putenv_garbage == NULL)
5626 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00005627#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005628}