blob: 31b0dde98a670af0c28379b24910d0d875c27aef [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 Rossum98bf58f2001-10-18 20:34:25 +000020#include "structseq.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000021
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000022#if defined(PYOS_OS2)
23#define INCL_DOS
24#define INCL_DOSERRORS
25#define INCL_DOSPROCESS
26#define INCL_NOPMAPI
27#include <os2.h>
28#endif
29
Guido van Rossumb6775db1994-08-01 11:34:53 +000030#include <sys/types.h>
31#include <sys/stat.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +000032
Guido van Rossum36bc6801995-06-14 22:54:23 +000033#ifdef HAVE_SYS_WAIT_H
34#include <sys/wait.h> /* For WNOHANG */
35#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000036
Guido van Rossuma376cc51996-12-05 23:43:35 +000037#ifdef HAVE_SIGNAL_H
38#include <signal.h>
39#endif
40
Guido van Rossumb6775db1994-08-01 11:34:53 +000041#ifdef HAVE_FCNTL_H
42#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000043#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000044
Guido van Rossuma6535fd2001-10-18 19:44:10 +000045#ifdef HAVE_GRP_H
46#include <grp.h>
47#endif
48
Guido van Rossuma4916fa1996-05-23 22:58:55 +000049/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000050/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000051#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000052#include <process.h>
53#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000054#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000055#define HAVE_GETCWD 1
56#define HAVE_OPENDIR 1
57#define HAVE_SYSTEM 1
58#if defined(__OS2__)
59#define HAVE_EXECV 1
60#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000061#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000062#include <process.h>
63#else
64#ifdef __BORLANDC__ /* Borland compiler */
65#define HAVE_EXECV 1
66#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000067#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
Guido van Rossum2242f2f2001-04-11 20:58:20 +000087#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
88#define HAVE_FORK1 1
89#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000090#define HAVE_GETCWD 1
91#define HAVE_GETEGID 1
92#define HAVE_GETEUID 1
93#define HAVE_GETGID 1
94#define HAVE_GETPPID 1
95#define HAVE_GETUID 1
96#define HAVE_KILL 1
97#define HAVE_OPENDIR 1
98#define HAVE_PIPE 1
99#define HAVE_POPEN 1
100#define HAVE_SYSTEM 1
101#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000102#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000103#endif /* _MSC_VER */
104#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000105#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000106#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000107
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000108#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000109
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000110#if defined(sun) && !defined(__SVR4)
111/* SunOS 4.1.4 doesn't have prototypes for these: */
112extern int rename(const char *, const char *);
113extern int pclose(FILE *);
114extern int fclose(FILE *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000115extern int fsync(int);
116extern int lstat(const char *, struct stat *);
117extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000118#endif
119
Guido van Rossum36bc6801995-06-14 22:54:23 +0000120#ifdef NeXT
121/* NeXT's <unistd.h> and <utime.h> aren't worth much */
122#undef HAVE_UNISTD_H
123#undef HAVE_UTIME_H
Guido van Rossumb9f866c1997-05-22 15:12:39 +0000124#define HAVE_WAITPID
Guido van Rossum36bc6801995-06-14 22:54:23 +0000125/* #undef HAVE_GETCWD */
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000126#define UNION_WAIT /* This should really be checked for by autoconf */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000127#endif
128
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000129#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000130#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000131extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000132#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000133#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000134extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000135#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000136extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000137#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000138#endif
139#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000140extern int chdir(char *);
141extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000142#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000143extern int chdir(const char *);
144extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000145#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000146#ifdef __BORLANDC__
147extern int chmod(const char *, int);
148#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000149extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000150#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000151extern int chown(const char *, uid_t, gid_t);
152extern char *getcwd(char *, int);
153extern char *strerror(int);
154extern int link(const char *, const char *);
155extern int rename(const char *, const char *);
156extern int stat(const char *, struct stat *);
157extern int unlink(const char *);
158extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000159#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000160extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000161#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000162#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000163extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000164#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000165#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000166
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000167#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000168
Guido van Rossumb6775db1994-08-01 11:34:53 +0000169#ifdef HAVE_UTIME_H
170#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000171#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000172
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000173#ifdef HAVE_SYS_UTIME_H
174#include <sys/utime.h>
175#define HAVE_UTIME_H /* pretend we do for the rest of this file */
176#endif /* HAVE_SYS_UTIME_H */
177
Guido van Rossumb6775db1994-08-01 11:34:53 +0000178#ifdef HAVE_SYS_TIMES_H
179#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000180#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000181
182#ifdef HAVE_SYS_PARAM_H
183#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000184#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000185
186#ifdef HAVE_SYS_UTSNAME_H
187#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000188#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000189
190#ifndef MAXPATHLEN
191#define MAXPATHLEN 1024
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000192#endif /* MAXPATHLEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000193
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000194#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000195#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000196#define NAMLEN(dirent) strlen((dirent)->d_name)
197#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000198#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000199#include <direct.h>
200#define NAMLEN(dirent) strlen((dirent)->d_name)
201#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000202#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000203#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000204#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000205#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000206#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000207#endif
208#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000209#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000210#endif
211#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000212#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000213#endif
214#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000215
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000216#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217#include <direct.h>
218#include <io.h>
219#include <process.h>
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000220#define WINDOWS_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000221#include <windows.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000222#ifdef MS_WIN32
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000223#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000224#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000225#else /* 16-bit Windows */
226#include <dos.h>
227#include <ctype.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000228#endif /* MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000229#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000230
Guido van Rossumd48f2521997-12-05 22:19:34 +0000231#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000233#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000234
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000235#ifdef UNION_WAIT
236/* Emulate some macros on systems that have a union instead of macros */
237
238#ifndef WIFEXITED
239#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
240#endif
241
242#ifndef WEXITSTATUS
243#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
244#endif
245
246#ifndef WTERMSIG
247#define WTERMSIG(u_wait) ((u_wait).w_termsig)
248#endif
249
250#endif /* UNION_WAIT */
251
Greg Wardb48bc172000-03-01 21:51:56 +0000252/* Don't use the "_r" form if we don't need it (also, won't have a
253 prototype for it, at least on Solaris -- maybe others as well?). */
254#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
255#define USE_CTERMID_R
256#endif
257
258#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
259#define USE_TMPNAM_R
260#endif
261
Fred Drake699f3522000-06-29 21:12:41 +0000262/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000263#undef STAT
Tim Peters6e13a562001-09-06 00:32:15 +0000264#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +0000265# define STAT _stati64
266# define FSTAT _fstati64
267# define STRUCT_STAT struct _stati64
268#else
269# define STAT stat
270# define FSTAT fstat
271# define STRUCT_STAT struct stat
272#endif
273
274
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000275/* Return a dictionary corresponding to the POSIX environment table */
276
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000277#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000278extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000279#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000280
Barry Warsaw53699e91996-12-10 23:23:01 +0000281static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000282convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000283{
Barry Warsaw53699e91996-12-10 23:23:01 +0000284 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000285 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000286 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000287 if (d == NULL)
288 return NULL;
289 if (environ == NULL)
290 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000291 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000292 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000293 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000294 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000295 char *p = strchr(*e, '=');
296 if (p == NULL)
297 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000298 k = PyString_FromStringAndSize(*e, (int)(p-*e));
299 if (k == NULL) {
300 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000301 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000302 }
303 v = PyString_FromString(p+1);
304 if (v == NULL) {
305 PyErr_Clear();
306 Py_DECREF(k);
307 continue;
308 }
309 if (PyDict_GetItem(d, k) == NULL) {
310 if (PyDict_SetItem(d, k, v) != 0)
311 PyErr_Clear();
312 }
313 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000314 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000315 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000316#if defined(PYOS_OS2)
317 {
318 APIRET rc;
319 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
320
321 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000322 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000323 PyObject *v = PyString_FromString(buffer);
324 PyDict_SetItemString(d, "BEGINLIBPATH", v);
325 Py_DECREF(v);
326 }
327 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
328 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
329 PyObject *v = PyString_FromString(buffer);
330 PyDict_SetItemString(d, "ENDLIBPATH", v);
331 Py_DECREF(v);
332 }
333 }
334#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000335 return d;
336}
337
338
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000339/* Set a POSIX-specific error from errno, and return NULL */
340
Barry Warsawd58d7641998-07-23 16:14:40 +0000341static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000342posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000343{
Barry Warsawca74da41999-02-09 19:31:45 +0000344 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000345}
Barry Warsawd58d7641998-07-23 16:14:40 +0000346static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000347posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000348{
Barry Warsawca74da41999-02-09 19:31:45 +0000349 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000350}
351
Mark Hammondef8b6542001-05-13 08:04:26 +0000352static PyObject *
353posix_error_with_allocated_filename(char* name)
354{
355 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
356 PyMem_Free(name);
357 return rc;
358}
359
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000360#ifdef MS_WIN32
361static PyObject *
362win32_error(char* function, char* filename)
363{
Mark Hammond33a6da92000-08-15 00:46:38 +0000364 /* XXX We should pass the function name along in the future.
365 (_winreg.c also wants to pass the function name.)
366 This would however require an additional param to the
367 Windows error object, which is non-trivial.
368 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000369 errno = GetLastError();
370 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000371 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000372 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000373 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000374}
375#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000376
Guido van Rossumd48f2521997-12-05 22:19:34 +0000377#if defined(PYOS_OS2)
378/**********************************************************************
379 * Helper Function to Trim and Format OS/2 Messages
380 **********************************************************************/
381 static void
382os2_formatmsg(char *msgbuf, int msglen, char *reason)
383{
384 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
385
386 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
387 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
388
389 while (lastc > msgbuf && isspace(*lastc))
390 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
391 }
392
393 /* Add Optional Reason Text */
394 if (reason) {
395 strcat(msgbuf, " : ");
396 strcat(msgbuf, reason);
397 }
398}
399
400/**********************************************************************
401 * Decode an OS/2 Operating System Error Code
402 *
403 * A convenience function to lookup an OS/2 error code and return a
404 * text message we can use to raise a Python exception.
405 *
406 * Notes:
407 * The messages for errors returned from the OS/2 kernel reside in
408 * the file OSO001.MSG in the \OS2 directory hierarchy.
409 *
410 **********************************************************************/
411 static char *
412os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
413{
414 APIRET rc;
415 ULONG msglen;
416
417 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
418 Py_BEGIN_ALLOW_THREADS
419 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
420 errorcode, "oso001.msg", &msglen);
421 Py_END_ALLOW_THREADS
422
423 if (rc == NO_ERROR)
424 os2_formatmsg(msgbuf, msglen, reason);
425 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000426 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000427 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000428
429 return msgbuf;
430}
431
432/* Set an OS/2-specific error and return NULL. OS/2 kernel
433 errors are not in a global variable e.g. 'errno' nor are
434 they congruent with posix error numbers. */
435
436static PyObject * os2_error(int code)
437{
438 char text[1024];
439 PyObject *v;
440
441 os2_strerror(text, sizeof(text), code, "");
442
443 v = Py_BuildValue("(is)", code, text);
444 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000445 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000446 Py_DECREF(v);
447 }
448 return NULL; /* Signal to Python that an Exception is Pending */
449}
450
451#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000452
453/* POSIX generic methods */
454
Barry Warsaw53699e91996-12-10 23:23:01 +0000455static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000456posix_int(PyObject *args, char *format, int (*func)(int))
Guido van Rossum21142a01999-01-08 21:05:37 +0000457{
458 int fd;
459 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000460 if (!PyArg_ParseTuple(args, format, &fd))
Guido van Rossum21142a01999-01-08 21:05:37 +0000461 return NULL;
462 Py_BEGIN_ALLOW_THREADS
463 res = (*func)(fd);
464 Py_END_ALLOW_THREADS
465 if (res < 0)
466 return posix_error();
467 Py_INCREF(Py_None);
468 return Py_None;
469}
470
471
472static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000473posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000474{
Mark Hammondef8b6542001-05-13 08:04:26 +0000475 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000476 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000477 if (!PyArg_ParseTuple(args, format,
478 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000479 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000480 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000481 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000482 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000483 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000484 return posix_error_with_allocated_filename(path1);
485 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000486 Py_INCREF(Py_None);
487 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000488}
489
Barry Warsaw53699e91996-12-10 23:23:01 +0000490static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000491posix_2str(PyObject *args, char *format,
492 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000493{
Mark Hammondef8b6542001-05-13 08:04:26 +0000494 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000495 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000496 if (!PyArg_ParseTuple(args, format,
497 Py_FileSystemDefaultEncoding, &path1,
498 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000499 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000500 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000501 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000502 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000503 PyMem_Free(path1);
504 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000505 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000506 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000507 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000508 Py_INCREF(Py_None);
509 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000510}
511
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000512static char stat_result__doc__[] =
513"stat_result: Result from stat or lstat.\n\n\
514This object may be accessed either as a tuple of\n\
515 (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
516or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
517\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000518Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000519they are available as attributes only.\n\
520\n\
521See os.stat for more information.\n";
522
523static PyStructSequence_Field stat_result_fields[] = {
524 {"st_mode", "protection bits"},
525 {"st_ino", "inode"},
526 {"st_dev", "device"},
527 {"st_nlink", "number of hard links"},
528 {"st_uid", "user ID of owner"},
529 {"st_gid", "group ID of owner"},
530 {"st_size", "total size, in bytes"},
531 {"st_atime", "time of last access"},
532 {"st_mtime", "time of last modification"},
533 {"st_ctime", "time of last change"},
534#ifdef HAVE_ST_BLKSIZE
535 {"st_blksize", "blocksize for filesystem I/O"},
536#endif
537#ifdef HAVE_ST_BLOCKS
538 {"st_blocks", "number of blocks allocated"},
539#endif
540#ifdef HAVE_ST_RDEV
541 {"st_rdev", "device type (if inode device)"},
542#endif
543 {0}
544};
545
546#ifdef HAVE_ST_BLKSIZE
547#define ST_BLKSIZE_IDX 10
548#else
549#define ST_BLKSIZE_IDX 9
550#endif
551
552#ifdef HAVE_ST_BLOCKS
553#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
554#else
555#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
556#endif
557
558#ifdef HAVE_ST_RDEV
559#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
560#else
561#define ST_RDEV_IDX ST_BLOCKS_IDX
562#endif
563
564static PyStructSequence_Desc stat_result_desc = {
565 "stat_result", /* name */
566 stat_result__doc__, /* doc */
567 stat_result_fields,
568 10
569};
570
571static char statvfs_result__doc__[] =
572"statvfs_result: Result from statvfs or fstatvfs.\n\n\
573This object may be accessed either as a tuple of\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000574 (bsize,frsize,blocks,bfree,bavail,files,ffree,favail,flag,namemax),\n\
575or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000576\n\
577See os.statvfs for more information.\n";
578
579static PyStructSequence_Field statvfs_result_fields[] = {
580 {"f_bsize", },
581 {"f_frsize", },
582 {"f_blocks", },
583 {"f_bfree", },
584 {"f_bavail", },
585 {"f_files", },
586 {"f_ffree", },
587 {"f_favail", },
588 {"f_flag", },
589 {"f_namemax",},
590 {0}
591};
592
593static PyStructSequence_Desc statvfs_result_desc = {
594 "statvfs_result", /* name */
595 statvfs_result__doc__, /* doc */
596 statvfs_result_fields,
597 10
598};
599
600static PyTypeObject StatResultType;
601static PyTypeObject StatVFSResultType;
602
Fred Drake699f3522000-06-29 21:12:41 +0000603/* pack a system stat C structure into the Python stat tuple
604 (used by posix_stat() and posix_fstat()) */
605static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000606_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000607{
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000608 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000609 if (v == NULL)
610 return NULL;
611
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000612 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000613#ifdef HAVE_LARGEFILE_SUPPORT
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000614 PyStructSequence_SET_ITEM(v, 1,
615 PyLong_FromLongLong((LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000616#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000617 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000618#endif
619#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000620 PyStructSequence_SET_ITEM(v, 2,
621 PyLong_FromLongLong((LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000622#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000623 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000624#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000625 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
626 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
627 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000628#ifdef HAVE_LARGEFILE_SUPPORT
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000629 PyStructSequence_SET_ITEM(v, 6,
630 PyLong_FromLongLong((LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000631#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000632 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000633#endif
634#if SIZEOF_TIME_T > SIZEOF_LONG
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000635 PyStructSequence_SET_ITEM(v, 7,
636 PyLong_FromLongLong((LONG_LONG)st.st_atime));
637 PyStructSequence_SET_ITEM(v, 8,
638 PyLong_FromLongLong((LONG_LONG)st.st_mtime));
639 PyStructSequence_SET_ITEM(v, 9,
640 PyLong_FromLongLong((LONG_LONG)st.st_ctime));
Fred Drake699f3522000-06-29 21:12:41 +0000641#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000642 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long)st.st_atime));
643 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long)st.st_mtime));
644 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long)st.st_ctime));
645#endif
646
647#ifdef HAVE_ST_BLKSIZE
648 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
649 PyInt_FromLong((long)st.st_blksize));
650#endif
651#ifdef HAVE_ST_BLOCKS
652 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
653 PyInt_FromLong((long)st.st_blocks));
654#endif
655#ifdef HAVE_ST_RDEV
656 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
657 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000658#endif
659
660 if (PyErr_Occurred()) {
661 Py_DECREF(v);
662 return NULL;
663 }
664
665 return v;
666}
667
Barry Warsaw53699e91996-12-10 23:23:01 +0000668static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000669posix_do_stat(PyObject *self, PyObject *args, char *format,
670 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000671{
Fred Drake699f3522000-06-29 21:12:41 +0000672 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +0000673 char *path = NULL; /* pass this to stat; do not free() it */
674 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000675 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000676
677#ifdef MS_WIN32
Tim Peters500bd032001-12-19 19:05:01 +0000678 int pathlen;
679 char pathcopy[MAX_PATH];
Guido van Rossumace88ae2000-04-21 18:54:45 +0000680#endif /* MS_WIN32 */
681
Mark Hammondef8b6542001-05-13 08:04:26 +0000682 if (!PyArg_ParseTuple(args, format,
683 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000684 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +0000685 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000686
687#ifdef MS_WIN32
688 pathlen = strlen(path);
689 /* the library call can blow up if the file name is too long! */
690 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +0000691 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000692 errno = ENAMETOOLONG;
693 return posix_error();
694 }
695
Tim Peters500bd032001-12-19 19:05:01 +0000696 /* Remove trailing slash or backslash, unless it's the current
697 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
698 */
699 if (pathlen > 0 &&
700 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
701 /* It does end with a slash -- exempt the root drive cases. */
702 /* XXX UNC root drives should also be exempted? */
703 if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
704 /* leave it alone */;
705 else {
706 /* nuke the trailing backslash */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000707 strncpy(pathcopy, path, pathlen);
Tim Peters500bd032001-12-19 19:05:01 +0000708 pathcopy[pathlen-1] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +0000709 path = pathcopy;
710 }
711 }
712#endif /* MS_WIN32 */
713
Barry Warsaw53699e91996-12-10 23:23:01 +0000714 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000715 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000716 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000717 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +0000718 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000719
Tim Peters500bd032001-12-19 19:05:01 +0000720 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000721 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000722}
723
724
725/* POSIX methods */
726
Guido van Rossum94f6f721999-01-06 18:42:14 +0000727static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000728"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000729Test for access to a file.";
730
731static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000732posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000733{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000734 char *path;
735 int mode;
736 int res;
737
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000738 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000739 return NULL;
740 Py_BEGIN_ALLOW_THREADS
741 res = access(path, mode);
742 Py_END_ALLOW_THREADS
743 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000744}
745
Guido van Rossumd371ff11999-01-25 16:12:23 +0000746#ifndef F_OK
747#define F_OK 0
748#endif
749#ifndef R_OK
750#define R_OK 4
751#endif
752#ifndef W_OK
753#define W_OK 2
754#endif
755#ifndef X_OK
756#define X_OK 1
757#endif
758
759#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000760static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000761"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000762Return the name of the terminal device connected to 'fd'.";
763
764static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000765posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000766{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000767 int id;
768 char *ret;
769
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000770 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000771 return NULL;
772
Guido van Rossum94f6f721999-01-06 18:42:14 +0000773 ret = ttyname(id);
774 if (ret == NULL)
775 return(posix_error());
776 return(PyString_FromString(ret));
777}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000778#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000779
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000780#ifdef HAVE_CTERMID
781static char posix_ctermid__doc__[] =
782"ctermid() -> String\n\
783Return the name of the controlling terminal for this process.";
784
785static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000786posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000787{
788 char *ret;
789 char buffer[L_ctermid];
790
791 if (!PyArg_ParseTuple(args, ":ctermid"))
792 return NULL;
793
Greg Wardb48bc172000-03-01 21:51:56 +0000794#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000795 ret = ctermid_r(buffer);
796#else
797 ret = ctermid(buffer);
798#endif
799 if (ret == NULL)
800 return(posix_error());
801 return(PyString_FromString(buffer));
802}
803#endif
804
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000805static char posix_chdir__doc__[] =
806"chdir(path) -> None\n\
807Change the current working directory to the specified path.";
808
Barry Warsaw53699e91996-12-10 23:23:01 +0000809static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000810posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000811{
Mark Hammondef8b6542001-05-13 08:04:26 +0000812 return posix_1str(args, "et:chdir", chdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000813}
814
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000815
816static char posix_chmod__doc__[] =
817"chmod(path, mode) -> None\n\
818Change the access permissions of a file.";
819
Barry Warsaw53699e91996-12-10 23:23:01 +0000820static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000821posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000822{
Mark Hammondef8b6542001-05-13 08:04:26 +0000823 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +0000824 int i;
825 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000826 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
827 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000828 return NULL;
829 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000830 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000831 Py_END_ALLOW_THREADS
832 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000833 return posix_error_with_allocated_filename(path);
834 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000835 Py_INCREF(Py_None);
836 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000837}
838
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000839
Martin v. Löwis244edc82001-10-04 22:44:26 +0000840#ifdef HAVE_CHROOT
841static char posix_chroot__doc__[] =
842"chroot(path) -> None\n\
843Change root directory to path.";
844
845static PyObject *
846posix_chroot(PyObject *self, PyObject *args)
847{
848 return posix_1str(args, "et:chroot", chroot);
849}
850#endif
851
Guido van Rossum21142a01999-01-08 21:05:37 +0000852#ifdef HAVE_FSYNC
853static char posix_fsync__doc__[] =
854"fsync(fildes) -> None\n\
855force write of file with filedescriptor to disk.";
856
857static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000858posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000859{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000860 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000861}
862#endif /* HAVE_FSYNC */
863
864#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000865
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000866#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000867extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
868#endif
869
Guido van Rossum21142a01999-01-08 21:05:37 +0000870static char posix_fdatasync__doc__[] =
871"fdatasync(fildes) -> None\n\
872force write of file with filedescriptor to disk.\n\
873 does not force update of metadata.";
874
875static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000876posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000877{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000878 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000879}
880#endif /* HAVE_FDATASYNC */
881
882
Fredrik Lundh10723342000-07-10 16:38:09 +0000883#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000884static char posix_chown__doc__[] =
885"chown(path, uid, gid) -> None\n\
886Change the owner and group id of path to the numeric uid and gid.";
887
Barry Warsaw53699e91996-12-10 23:23:01 +0000888static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000889posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000890{
Mark Hammondef8b6542001-05-13 08:04:26 +0000891 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +0000892 int uid, gid;
893 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000894 if (!PyArg_ParseTuple(args, "etii:chown",
895 Py_FileSystemDefaultEncoding, &path,
896 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +0000897 return NULL;
898 Py_BEGIN_ALLOW_THREADS
899 res = chown(path, (uid_t) uid, (gid_t) gid);
900 Py_END_ALLOW_THREADS
901 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000902 return posix_error_with_allocated_filename(path);
903 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +0000904 Py_INCREF(Py_None);
905 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000906}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000907#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000908
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000909
Guido van Rossum36bc6801995-06-14 22:54:23 +0000910#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000911static char posix_getcwd__doc__[] =
912"getcwd() -> path\n\
913Return a string representing the current working directory.";
914
Barry Warsaw53699e91996-12-10 23:23:01 +0000915static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000916posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000917{
918 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000919 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000920 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000921 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000922 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000923 res = getcwd(buf, sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +0000924 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000925 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000926 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000927 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000928}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000929#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000930
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000931
Guido van Rossumb6775db1994-08-01 11:34:53 +0000932#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000933static char posix_link__doc__[] =
934"link(src, dst) -> None\n\
935Create a hard link to a file.";
936
Barry Warsaw53699e91996-12-10 23:23:01 +0000937static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000938posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000939{
Mark Hammondef8b6542001-05-13 08:04:26 +0000940 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000941}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000942#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000943
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000944
945static char posix_listdir__doc__[] =
946"listdir(path) -> list_of_strings\n\
947Return a list containing the names of the entries in the directory.\n\
948\n\
949 path: path of directory to list\n\
950\n\
951The list is in arbitrary order. It does not include the special\n\
952entries '.' and '..' even if they are present in the directory.";
953
Barry Warsaw53699e91996-12-10 23:23:01 +0000954static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000955posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000956{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000957 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000958 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000959#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000960
Barry Warsaw53699e91996-12-10 23:23:01 +0000961 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000962 HANDLE hFindFile;
963 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +0000964 /* MAX_PATH characters could mean a bigger encoded string */
965 char namebuf[MAX_PATH*2+5];
966 char *bufptr = namebuf;
967 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Tim Peters0bb44a42000-09-15 07:44:49 +0000968 char ch;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000969
Mark Hammondef8b6542001-05-13 08:04:26 +0000970 if (!PyArg_ParseTuple(args, "et#:listdir",
971 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000972 return NULL;
Tim Peters0bb44a42000-09-15 07:44:49 +0000973 ch = namebuf[len-1];
974 if (ch != '/' && ch != '\\' && ch != ':')
Guido van Rossumb6775db1994-08-01 11:34:53 +0000975 namebuf[len++] = '/';
976 strcpy(namebuf + len, "*.*");
977
Barry Warsaw53699e91996-12-10 23:23:01 +0000978 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000979 return NULL;
980
981 hFindFile = FindFirstFile(namebuf, &FileData);
982 if (hFindFile == INVALID_HANDLE_VALUE) {
983 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000984 if (errno == ERROR_FILE_NOT_FOUND)
985 return PyList_New(0);
Mark Hammondef8b6542001-05-13 08:04:26 +0000986 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000987 }
988 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000989 if (FileData.cFileName[0] == '.' &&
990 (FileData.cFileName[1] == '\0' ||
991 FileData.cFileName[1] == '.' &&
992 FileData.cFileName[2] == '\0'))
993 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +0000994 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000995 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000996 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000997 d = NULL;
998 break;
999 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001000 if (PyList_Append(d, v) != 0) {
1001 Py_DECREF(v);
1002 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001003 d = NULL;
1004 break;
1005 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001006 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001007 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1008
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001009 if (FindClose(hFindFile) == FALSE)
Mark Hammondef8b6542001-05-13 08:04:26 +00001010 return win32_error("FindClose", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001011
1012 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001013
Tim Peters0bb44a42000-09-15 07:44:49 +00001014#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001015
1016#ifndef MAX_PATH
1017#define MAX_PATH 250
1018#endif
1019 char *name, *pt;
1020 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +00001021 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001022 char namebuf[MAX_PATH+5];
1023 struct _find_t ep;
1024
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001025 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001026 return NULL;
1027 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001028 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001029 return NULL;
1030 }
1031 strcpy(namebuf, name);
1032 for (pt = namebuf; *pt; pt++)
1033 if (*pt == '/')
1034 *pt = '\\';
1035 if (namebuf[len-1] != '\\')
1036 namebuf[len++] = '\\';
1037 strcpy(namebuf + len, "*.*");
1038
Barry Warsaw53699e91996-12-10 23:23:01 +00001039 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001040 return NULL;
1041
1042 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +00001043 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
1044 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001045 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001046 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001047 }
1048 do {
1049 if (ep.name[0] == '.' &&
1050 (ep.name[1] == '\0' ||
1051 ep.name[1] == '.' &&
1052 ep.name[2] == '\0'))
1053 continue;
1054 strcpy(namebuf, ep.name);
1055 for (pt = namebuf; *pt; pt++)
1056 if (isupper(*pt))
1057 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +00001058 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001059 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001060 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001061 d = NULL;
1062 break;
1063 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001064 if (PyList_Append(d, v) != 0) {
1065 Py_DECREF(v);
1066 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001067 d = NULL;
1068 break;
1069 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001070 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001071 } while (_dos_findnext(&ep) == 0);
1072
1073 return d;
1074
Tim Peters0bb44a42000-09-15 07:44:49 +00001075#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001076
1077#ifndef MAX_PATH
1078#define MAX_PATH CCHMAXPATH
1079#endif
1080 char *name, *pt;
1081 int len;
1082 PyObject *d, *v;
1083 char namebuf[MAX_PATH+5];
1084 HDIR hdir = 1;
1085 ULONG srchcnt = 1;
1086 FILEFINDBUF3 ep;
1087 APIRET rc;
1088
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001089 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001090 return NULL;
1091 if (len >= MAX_PATH) {
1092 PyErr_SetString(PyExc_ValueError, "path too long");
1093 return NULL;
1094 }
1095 strcpy(namebuf, name);
1096 for (pt = namebuf; *pt; pt++)
1097 if (*pt == '/')
1098 *pt = '\\';
1099 if (namebuf[len-1] != '\\')
1100 namebuf[len++] = '\\';
1101 strcpy(namebuf + len, "*.*");
1102
1103 if ((d = PyList_New(0)) == NULL)
1104 return NULL;
1105
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001106 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1107 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001108 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001109 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1110 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1111 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001112
1113 if (rc != NO_ERROR) {
1114 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001115 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001116 }
1117
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001118 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001119 do {
1120 if (ep.achName[0] == '.'
1121 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001122 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001123
1124 strcpy(namebuf, ep.achName);
1125
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001126 /* Leave Case of Name Alone -- In Native Form */
1127 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001128
1129 v = PyString_FromString(namebuf);
1130 if (v == NULL) {
1131 Py_DECREF(d);
1132 d = NULL;
1133 break;
1134 }
1135 if (PyList_Append(d, v) != 0) {
1136 Py_DECREF(v);
1137 Py_DECREF(d);
1138 d = NULL;
1139 break;
1140 }
1141 Py_DECREF(v);
1142 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1143 }
1144
1145 return d;
1146#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001147
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001148 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001149 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001150 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001151 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001152 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001153 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001154 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001155 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001156 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001157 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001158 closedir(dirp);
1159 return NULL;
1160 }
1161 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001162 if (ep->d_name[0] == '.' &&
1163 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001164 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001165 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001166 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001167 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001168 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001169 d = NULL;
1170 break;
1171 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001172 if (PyList_Append(d, v) != 0) {
1173 Py_DECREF(v);
1174 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001175 d = NULL;
1176 break;
1177 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001178 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001179 }
1180 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001181
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001182 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001183
Tim Peters0bb44a42000-09-15 07:44:49 +00001184#endif /* which OS */
1185} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001186
Mark Hammondef8b6542001-05-13 08:04:26 +00001187#ifdef MS_WIN32
1188/* A helper function for abspath on win32 */
1189static PyObject *
1190posix__getfullpathname(PyObject *self, PyObject *args)
1191{
1192 /* assume encoded strings wont more than double no of chars */
1193 char inbuf[MAX_PATH*2];
1194 char *inbufp = inbuf;
1195 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1196 char outbuf[MAX_PATH*2];
1197 char *temp;
1198 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1199 Py_FileSystemDefaultEncoding, &inbufp,
1200 &insize))
1201 return NULL;
1202 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1203 outbuf, &temp))
1204 return win32_error("GetFullPathName", inbuf);
1205 return PyString_FromString(outbuf);
1206} /* end of posix__getfullpathname */
1207#endif /* MS_WIN32 */
1208
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001209static char posix_mkdir__doc__[] =
1210"mkdir(path [, mode=0777]) -> None\n\
1211Create a directory.";
1212
Barry Warsaw53699e91996-12-10 23:23:01 +00001213static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001214posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001215{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001216 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001217 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001218 int mode = 0777;
Mark Hammondef8b6542001-05-13 08:04:26 +00001219 if (!PyArg_ParseTuple(args, "et|i:mkdir",
1220 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001221 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001222 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001223#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001224 res = mkdir(path);
1225#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001226 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001227#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001228 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001229 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001230 return posix_error_with_allocated_filename(path);
1231 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001232 Py_INCREF(Py_None);
1233 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001234}
1235
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001236
Guido van Rossumb6775db1994-08-01 11:34:53 +00001237#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001238#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1239#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1240#include <sys/resource.h>
1241#endif
1242#endif
1243
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001244static char posix_nice__doc__[] =
1245"nice(inc) -> new_priority\n\
1246Decrease the priority of process and return new priority.";
1247
Barry Warsaw53699e91996-12-10 23:23:01 +00001248static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001249posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001250{
1251 int increment, value;
1252
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001253 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001254 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001255
1256 /* There are two flavours of 'nice': one that returns the new
1257 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001258 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1259 the use of getpriority() to get the new priority.
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001260
1261 If we are of the nice family that returns the new priority, we
1262 need to clear errno before the call, and check if errno is filled
1263 before calling posix_error() on a returnvalue of -1, because the
1264 -1 may be the actual new priority! */
1265
1266 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001267 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001268#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001269 if (value == 0)
1270 value = getpriority(PRIO_PROCESS, 0);
1271#endif
1272 if (value == -1 && errno != 0)
1273 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001274 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001275 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001276}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001277#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001278
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001279
1280static char posix_rename__doc__[] =
1281"rename(old, new) -> None\n\
1282Rename a file or directory.";
1283
Barry Warsaw53699e91996-12-10 23:23:01 +00001284static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001285posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001286{
Mark Hammondef8b6542001-05-13 08:04:26 +00001287 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001288}
1289
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001290
1291static char posix_rmdir__doc__[] =
1292"rmdir(path) -> None\n\
1293Remove a directory.";
1294
Barry Warsaw53699e91996-12-10 23:23:01 +00001295static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001296posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001297{
Mark Hammondef8b6542001-05-13 08:04:26 +00001298 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001299}
1300
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001301
1302static char posix_stat__doc__[] =
1303"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1304Perform a stat system call on the given path.";
1305
Barry Warsaw53699e91996-12-10 23:23:01 +00001306static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001307posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001308{
Mark Hammondef8b6542001-05-13 08:04:26 +00001309 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001310}
1311
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001312
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001313#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001314static char posix_system__doc__[] =
1315"system(command) -> exit_status\n\
1316Execute the command (a string) in a subshell.";
1317
Barry Warsaw53699e91996-12-10 23:23:01 +00001318static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001319posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001320{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001321 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001322 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001323 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001324 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001325 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001326 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001327 Py_END_ALLOW_THREADS
1328 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001329}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001330#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001331
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001332
1333static char posix_umask__doc__[] =
1334"umask(new_mask) -> old_mask\n\
1335Set the current numeric umask and return the previous umask.";
1336
Barry Warsaw53699e91996-12-10 23:23:01 +00001337static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001338posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001339{
1340 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001341 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001342 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001343 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001344 if (i < 0)
1345 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001346 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001347}
1348
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001349
1350static char posix_unlink__doc__[] =
1351"unlink(path) -> None\n\
1352Remove a file (same as remove(path)).";
1353
1354static char posix_remove__doc__[] =
1355"remove(path) -> None\n\
1356Remove a file (same as unlink(path)).";
1357
Barry Warsaw53699e91996-12-10 23:23:01 +00001358static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001359posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001360{
Mark Hammondef8b6542001-05-13 08:04:26 +00001361 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001362}
1363
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001364
Guido van Rossumb6775db1994-08-01 11:34:53 +00001365#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001366static char posix_uname__doc__[] =
1367"uname() -> (sysname, nodename, release, version, machine)\n\
1368Return a tuple identifying the current operating system.";
1369
Barry Warsaw53699e91996-12-10 23:23:01 +00001370static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001371posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001372{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001373 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001374 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001375 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001376 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001377 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001378 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001379 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001380 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001381 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001382 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001383 u.sysname,
1384 u.nodename,
1385 u.release,
1386 u.version,
1387 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001388}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001389#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001390
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001391
1392static char posix_utime__doc__[] =
1393"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001394utime(path, None) -> None\n\
1395Set the access and modified time of the file to the given values. If the\n\
1396second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001397
Barry Warsaw53699e91996-12-10 23:23:01 +00001398static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001399posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001400{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001401 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001402 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001403 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001404 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001405
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001406/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001407#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001408 struct utimbuf buf;
1409#define ATIME buf.actime
1410#define MTIME buf.modtime
1411#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001412#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001413 time_t buf[2];
1414#define ATIME buf[0]
1415#define MTIME buf[1]
1416#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001417#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001418
Barry Warsaw3cef8562000-05-01 16:17:24 +00001419 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001420 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001421 if (arg == Py_None) {
1422 /* optional time values not given */
1423 Py_BEGIN_ALLOW_THREADS
1424 res = utime(path, NULL);
1425 Py_END_ALLOW_THREADS
1426 }
1427 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1428 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001429 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001430 return NULL;
1431 }
1432 else {
1433 ATIME = atime;
1434 MTIME = mtime;
1435 Py_BEGIN_ALLOW_THREADS
1436 res = utime(path, UTIME_ARG);
1437 Py_END_ALLOW_THREADS
1438 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001439 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001440 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001441 Py_INCREF(Py_None);
1442 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001443#undef UTIME_ARG
1444#undef ATIME
1445#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001446}
1447
Guido van Rossum85e3b011991-06-03 12:42:10 +00001448
Guido van Rossum3b066191991-06-04 19:40:25 +00001449/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001450
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001451static char posix__exit__doc__[] =
1452"_exit(status)\n\
1453Exit to the system with specified status, without normal exit processing.";
1454
Barry Warsaw53699e91996-12-10 23:23:01 +00001455static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001456posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001457{
1458 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001459 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001460 return NULL;
1461 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001462 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001463}
1464
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001465
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001466#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001467static char posix_execv__doc__[] =
1468"execv(path, args)\n\
1469Execute an executable path with arguments, replacing current process.\n\
1470\n\
1471 path: path of executable file\n\
1472 args: tuple or list of strings";
1473
Barry Warsaw53699e91996-12-10 23:23:01 +00001474static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001475posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001476{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001477 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001478 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001479 char **argvlist;
1480 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001481 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001482
Guido van Rossum89b33251993-10-22 14:26:06 +00001483 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001484 argv is a list or tuple of strings. */
1485
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001486 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001487 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001488 if (PyList_Check(argv)) {
1489 argc = PyList_Size(argv);
1490 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001491 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001492 else if (PyTuple_Check(argv)) {
1493 argc = PyTuple_Size(argv);
1494 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001495 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001496 else {
Fred Drake661ea262000-10-24 19:57:45 +00001497 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001498 return NULL;
1499 }
1500
1501 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001502 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001503 return NULL;
1504 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001505
Barry Warsaw53699e91996-12-10 23:23:01 +00001506 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001507 if (argvlist == NULL)
1508 return NULL;
1509 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001510 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1511 PyMem_DEL(argvlist);
Guido van Rossum50422b42000-04-26 20:34:28 +00001512 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001513 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001514 return NULL;
1515
Guido van Rossum85e3b011991-06-03 12:42:10 +00001516 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001517 }
1518 argvlist[argc] = NULL;
1519
Guido van Rossumb6775db1994-08-01 11:34:53 +00001520#ifdef BAD_EXEC_PROTOTYPES
1521 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001522#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001523 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001524#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001525
Guido van Rossum85e3b011991-06-03 12:42:10 +00001526 /* If we get here it's definitely an error */
1527
Barry Warsaw53699e91996-12-10 23:23:01 +00001528 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001529 return posix_error();
1530}
1531
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001532
1533static char posix_execve__doc__[] =
1534"execve(path, args, env)\n\
1535Execute a path with arguments and environment, replacing current process.\n\
1536\n\
1537 path: path of executable file\n\
1538 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001539 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001540
Barry Warsaw53699e91996-12-10 23:23:01 +00001541static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001542posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001543{
1544 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001545 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001546 char **argvlist;
1547 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001548 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001549 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001550 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001551
1552 /* execve has three arguments: (path, argv, env), where
1553 argv is a list or tuple of strings and env is a dictionary
1554 like posix.environ. */
1555
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001556 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001557 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001558 if (PyList_Check(argv)) {
1559 argc = PyList_Size(argv);
1560 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001561 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001562 else if (PyTuple_Check(argv)) {
1563 argc = PyTuple_Size(argv);
1564 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001565 }
1566 else {
Fred Drake661ea262000-10-24 19:57:45 +00001567 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001568 return NULL;
1569 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001570 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001571 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001572 return NULL;
1573 }
1574
Guido van Rossum50422b42000-04-26 20:34:28 +00001575 if (argc == 0) {
1576 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001577 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001578 return NULL;
1579 }
1580
Barry Warsaw53699e91996-12-10 23:23:01 +00001581 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001582 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001583 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001584 return NULL;
1585 }
1586 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001587 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001588 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001589 &argvlist[i]))
1590 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001591 goto fail_1;
1592 }
1593 }
1594 argvlist[argc] = NULL;
1595
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001596 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001597 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001598 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001599 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001600 goto fail_1;
1601 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001602 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001603 keys = PyMapping_Keys(env);
1604 vals = PyMapping_Values(env);
1605 if (!keys || !vals)
1606 goto fail_2;
1607
1608 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001609 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001610 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001611
1612 key = PyList_GetItem(keys, pos);
1613 val = PyList_GetItem(vals, pos);
1614 if (!key || !val)
1615 goto fail_2;
1616
Fred Drake661ea262000-10-24 19:57:45 +00001617 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1618 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001619 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001620 goto fail_2;
1621 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001622
1623#if defined(PYOS_OS2)
1624 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1625 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1626#endif
Tim Petersc8996f52001-12-03 20:41:00 +00001627 len = PyString_Size(key) + PyString_Size(val) + 2;
1628 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001629 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001630 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001631 goto fail_2;
1632 }
Tim Petersc8996f52001-12-03 20:41:00 +00001633 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001634 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001635#if defined(PYOS_OS2)
1636 }
1637#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001638 }
1639 envlist[envc] = 0;
1640
Guido van Rossumb6775db1994-08-01 11:34:53 +00001641
1642#ifdef BAD_EXEC_PROTOTYPES
1643 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001644#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001645 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001646#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001647
1648 /* If we get here it's definitely an error */
1649
1650 (void) posix_error();
1651
1652 fail_2:
1653 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001654 PyMem_DEL(envlist[envc]);
1655 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001656 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001657 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001658 Py_XDECREF(vals);
1659 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001660 return NULL;
1661}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001662#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001663
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001664
Guido van Rossuma1065681999-01-25 23:20:23 +00001665#ifdef HAVE_SPAWNV
1666static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001667"spawnv(mode, path, args)\n\
Tim Peters25059d32001-12-07 20:35:43 +00001668Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001669\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001670 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001671 path: path of executable file\n\
1672 args: tuple or list of strings";
1673
1674static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001675posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001676{
1677 char *path;
1678 PyObject *argv;
1679 char **argvlist;
1680 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00001681 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001682 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001683
1684 /* spawnv has three arguments: (mode, path, argv), where
1685 argv is a list or tuple of strings. */
1686
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001687 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001688 return NULL;
1689 if (PyList_Check(argv)) {
1690 argc = PyList_Size(argv);
1691 getitem = PyList_GetItem;
1692 }
1693 else if (PyTuple_Check(argv)) {
1694 argc = PyTuple_Size(argv);
1695 getitem = PyTuple_GetItem;
1696 }
1697 else {
Martin v. Löwise75f0e42001-11-24 09:31:44 +00001698 PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001699 return NULL;
1700 }
1701
1702 argvlist = PyMem_NEW(char *, argc+1);
1703 if (argvlist == NULL)
1704 return NULL;
1705 for (i = 0; i < argc; i++) {
1706 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1707 PyMem_DEL(argvlist);
Fred Drake137507e2000-06-01 02:02:46 +00001708 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001709 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001710 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001711 }
1712 }
1713 argvlist[argc] = NULL;
1714
Guido van Rossum246bc171999-02-01 23:54:31 +00001715 if (mode == _OLD_P_OVERLAY)
1716 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00001717
1718 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001719 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00001720 Py_END_ALLOW_THREADS
1721
Guido van Rossuma1065681999-01-25 23:20:23 +00001722 PyMem_DEL(argvlist);
1723
Fred Drake699f3522000-06-29 21:12:41 +00001724 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001725 return posix_error();
1726 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001727#if SIZEOF_LONG == SIZEOF_VOID_P
1728 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001729#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001730 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001731#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001732}
1733
1734
1735static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001736"spawnve(mode, path, args, env)\n\
Tim Peters25059d32001-12-07 20:35:43 +00001737Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001738\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001739 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001740 path: path of executable file\n\
1741 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001742 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001743
1744static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001745posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001746{
1747 char *path;
1748 PyObject *argv, *env;
1749 char **argvlist;
1750 char **envlist;
1751 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1752 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00001753 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001754 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001755
1756 /* spawnve has four arguments: (mode, path, argv, env), where
1757 argv is a list or tuple of strings and env is a dictionary
1758 like posix.environ. */
1759
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001760 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001761 return NULL;
1762 if (PyList_Check(argv)) {
1763 argc = PyList_Size(argv);
1764 getitem = PyList_GetItem;
1765 }
1766 else if (PyTuple_Check(argv)) {
1767 argc = PyTuple_Size(argv);
1768 getitem = PyTuple_GetItem;
1769 }
1770 else {
Fred Drake661ea262000-10-24 19:57:45 +00001771 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001772 return NULL;
1773 }
1774 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001775 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001776 return NULL;
1777 }
1778
1779 argvlist = PyMem_NEW(char *, argc+1);
1780 if (argvlist == NULL) {
1781 PyErr_NoMemory();
1782 return NULL;
1783 }
1784 for (i = 0; i < argc; i++) {
1785 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001786 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001787 &argvlist[i]))
1788 {
1789 goto fail_1;
1790 }
1791 }
1792 argvlist[argc] = NULL;
1793
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001794 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001795 envlist = PyMem_NEW(char *, i + 1);
1796 if (envlist == NULL) {
1797 PyErr_NoMemory();
1798 goto fail_1;
1799 }
1800 envc = 0;
1801 keys = PyMapping_Keys(env);
1802 vals = PyMapping_Values(env);
1803 if (!keys || !vals)
1804 goto fail_2;
1805
1806 for (pos = 0; pos < i; pos++) {
1807 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001808 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00001809
1810 key = PyList_GetItem(keys, pos);
1811 val = PyList_GetItem(vals, pos);
1812 if (!key || !val)
1813 goto fail_2;
1814
Fred Drake661ea262000-10-24 19:57:45 +00001815 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1816 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001817 {
1818 goto fail_2;
1819 }
Tim Petersc8996f52001-12-03 20:41:00 +00001820 len = PyString_Size(key) + PyString_Size(val) + 2;
1821 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00001822 if (p == NULL) {
1823 PyErr_NoMemory();
1824 goto fail_2;
1825 }
Tim Petersc8996f52001-12-03 20:41:00 +00001826 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00001827 envlist[envc++] = p;
1828 }
1829 envlist[envc] = 0;
1830
Guido van Rossum246bc171999-02-01 23:54:31 +00001831 if (mode == _OLD_P_OVERLAY)
1832 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00001833
1834 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001835 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00001836 Py_END_ALLOW_THREADS
1837
Fred Drake699f3522000-06-29 21:12:41 +00001838 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001839 (void) posix_error();
1840 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001841#if SIZEOF_LONG == SIZEOF_VOID_P
1842 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001843#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001844 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001845#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001846
1847 fail_2:
1848 while (--envc >= 0)
1849 PyMem_DEL(envlist[envc]);
1850 PyMem_DEL(envlist);
1851 fail_1:
1852 PyMem_DEL(argvlist);
1853 Py_XDECREF(vals);
1854 Py_XDECREF(keys);
1855 return res;
1856}
1857#endif /* HAVE_SPAWNV */
1858
1859
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001860#ifdef HAVE_FORK1
1861static char posix_fork1__doc__[] =
1862"fork1() -> pid\n\
1863Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1864\n\
1865Return 0 to child process and PID of child to parent process.";
1866
1867static PyObject *
1868posix_fork1(self, args)
1869 PyObject *self;
1870 PyObject *args;
1871{
1872 int pid;
1873 if (!PyArg_ParseTuple(args, ":fork1"))
1874 return NULL;
1875 pid = fork1();
1876 if (pid == -1)
1877 return posix_error();
1878 PyOS_AfterFork();
1879 return PyInt_FromLong((long)pid);
1880}
1881#endif
1882
1883
Guido van Rossumad0ee831995-03-01 10:34:45 +00001884#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001885static char posix_fork__doc__[] =
1886"fork() -> pid\n\
1887Fork a child process.\n\
1888\n\
1889Return 0 to child process and PID of child to parent process.";
1890
Barry Warsaw53699e91996-12-10 23:23:01 +00001891static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001892posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001893{
1894 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001895 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001896 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001897 pid = fork();
1898 if (pid == -1)
1899 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001900 if (pid == 0)
1901 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001902 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001903}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001904#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001905
Fred Drake8cef4cf2000-06-28 16:40:38 +00001906#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1907#ifdef HAVE_PTY_H
1908#include <pty.h>
1909#else
1910#ifdef HAVE_LIBUTIL_H
1911#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001912#endif /* HAVE_LIBUTIL_H */
1913#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001914#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001915
Thomas Wouters70c21a12000-07-14 14:28:33 +00001916#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001917static char posix_openpty__doc__[] =
1918"openpty() -> (master_fd, slave_fd)\n\
1919Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1920
1921static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001922posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001923{
1924 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001925#ifndef HAVE_OPENPTY
1926 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001927#endif
1928
Fred Drake8cef4cf2000-06-28 16:40:38 +00001929 if (!PyArg_ParseTuple(args, ":openpty"))
1930 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001931
1932#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001933 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1934 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001935#else
1936 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1937 if (slave_name == NULL)
1938 return posix_error();
1939
1940 slave_fd = open(slave_name, O_RDWR);
1941 if (slave_fd < 0)
1942 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001943#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001944
Fred Drake8cef4cf2000-06-28 16:40:38 +00001945 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001946
Fred Drake8cef4cf2000-06-28 16:40:38 +00001947}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001948#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001949
1950#ifdef HAVE_FORKPTY
1951static char posix_forkpty__doc__[] =
1952"forkpty() -> (pid, master_fd)\n\
1953Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1954Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1955To both, return fd of newly opened pseudo-terminal.\n";
1956
1957static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001958posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001959{
1960 int master_fd, pid;
1961
1962 if (!PyArg_ParseTuple(args, ":forkpty"))
1963 return NULL;
1964 pid = forkpty(&master_fd, NULL, NULL, NULL);
1965 if (pid == -1)
1966 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001967 if (pid == 0)
1968 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001969 return Py_BuildValue("(ii)", pid, master_fd);
1970}
1971#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001972
Guido van Rossumad0ee831995-03-01 10:34:45 +00001973#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001974static char posix_getegid__doc__[] =
1975"getegid() -> egid\n\
1976Return the current process's effective group id.";
1977
Barry Warsaw53699e91996-12-10 23:23:01 +00001978static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001979posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001980{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001981 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001982 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001983 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001984}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001985#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001986
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001987
Guido van Rossumad0ee831995-03-01 10:34:45 +00001988#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001989static char posix_geteuid__doc__[] =
1990"geteuid() -> euid\n\
1991Return the current process's effective user id.";
1992
Barry Warsaw53699e91996-12-10 23:23:01 +00001993static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001994posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001995{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001996 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001997 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001998 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001999}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002000#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002001
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002002
Guido van Rossumad0ee831995-03-01 10:34:45 +00002003#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002004static char posix_getgid__doc__[] =
2005"getgid() -> gid\n\
2006Return the current process's group id.";
2007
Barry Warsaw53699e91996-12-10 23:23:01 +00002008static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002009posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002010{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002011 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002012 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002013 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002014}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002015#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002016
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002017
2018static char posix_getpid__doc__[] =
2019"getpid() -> pid\n\
2020Return the current process id";
2021
Barry Warsaw53699e91996-12-10 23:23:01 +00002022static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002023posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002024{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002025 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002026 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002027 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002028}
2029
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002030
Fred Drakec9680921999-12-13 16:37:25 +00002031#ifdef HAVE_GETGROUPS
2032static char posix_getgroups__doc__[] = "\
2033getgroups() -> list of group IDs\n\
2034Return list of supplemental group IDs for the process.";
2035
2036static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002037posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002038{
2039 PyObject *result = NULL;
2040
2041 if (PyArg_ParseTuple(args, ":getgroups")) {
2042#ifdef NGROUPS_MAX
2043#define MAX_GROUPS NGROUPS_MAX
2044#else
2045 /* defined to be 16 on Solaris7, so this should be a small number */
2046#define MAX_GROUPS 64
2047#endif
2048 gid_t grouplist[MAX_GROUPS];
2049 int n;
2050
2051 n = getgroups(MAX_GROUPS, grouplist);
2052 if (n < 0)
2053 posix_error();
2054 else {
2055 result = PyList_New(n);
2056 if (result != NULL) {
2057 PyObject *o;
2058 int i;
2059 for (i = 0; i < n; ++i) {
2060 o = PyInt_FromLong((long)grouplist[i]);
2061 if (o == NULL) {
2062 Py_DECREF(result);
2063 result = NULL;
2064 break;
2065 }
2066 PyList_SET_ITEM(result, i, o);
2067 }
2068 }
2069 }
2070 }
2071 return result;
2072}
2073#endif
2074
Guido van Rossumb6775db1994-08-01 11:34:53 +00002075#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002076static char posix_getpgrp__doc__[] =
2077"getpgrp() -> pgrp\n\
2078Return the current process group id.";
2079
Barry Warsaw53699e91996-12-10 23:23:01 +00002080static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002081posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002082{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002083 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002084 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002085#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002086 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002087#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002088 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002089#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002090}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002091#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002092
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002093
Guido van Rossumb6775db1994-08-01 11:34:53 +00002094#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002095static char posix_setpgrp__doc__[] =
2096"setpgrp() -> None\n\
2097Make this process a session leader.";
2098
Barry Warsaw53699e91996-12-10 23:23:01 +00002099static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002100posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002101{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002102 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002103 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002104#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002105 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002106#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002107 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002108#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002109 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002110 Py_INCREF(Py_None);
2111 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002112}
2113
Guido van Rossumb6775db1994-08-01 11:34:53 +00002114#endif /* HAVE_SETPGRP */
2115
Guido van Rossumad0ee831995-03-01 10:34:45 +00002116#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002117static char posix_getppid__doc__[] =
2118"getppid() -> ppid\n\
2119Return the parent's process id.";
2120
Barry Warsaw53699e91996-12-10 23:23:01 +00002121static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002122posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002123{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002124 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002125 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002126 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002127}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002128#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002129
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002130
Fred Drake12c6e2d1999-12-14 21:25:03 +00002131#ifdef HAVE_GETLOGIN
2132static char posix_getlogin__doc__[] = "\
2133getlogin() -> string\n\
2134Return the actual login name.";
2135
2136static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002137posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002138{
2139 PyObject *result = NULL;
2140
2141 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002142 char *name;
2143 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002144
Fred Drakea30680b2000-12-06 21:24:28 +00002145 errno = 0;
2146 name = getlogin();
2147 if (name == NULL) {
2148 if (errno)
2149 posix_error();
2150 else
2151 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002152 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002153 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002154 else
2155 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002156 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002157 }
2158 return result;
2159}
2160#endif
2161
Guido van Rossumad0ee831995-03-01 10:34:45 +00002162#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002163static char posix_getuid__doc__[] =
2164"getuid() -> uid\n\
2165Return the current process's user id.";
2166
Barry Warsaw53699e91996-12-10 23:23:01 +00002167static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002168posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002169{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002170 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002171 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002172 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002173}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002174#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002175
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002176
Guido van Rossumad0ee831995-03-01 10:34:45 +00002177#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002178static char posix_kill__doc__[] =
2179"kill(pid, sig) -> None\n\
2180Kill a process with a signal.";
2181
Barry Warsaw53699e91996-12-10 23:23:01 +00002182static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002183posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002184{
2185 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002186 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002187 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002188#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002189 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2190 APIRET rc;
2191 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002192 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002193
2194 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2195 APIRET rc;
2196 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002197 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002198
2199 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002200 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002201#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002202 if (kill(pid, sig) == -1)
2203 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002204#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002205 Py_INCREF(Py_None);
2206 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002207}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002208#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002209
Guido van Rossumc0125471996-06-28 18:55:32 +00002210#ifdef HAVE_PLOCK
2211
2212#ifdef HAVE_SYS_LOCK_H
2213#include <sys/lock.h>
2214#endif
2215
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002216static char posix_plock__doc__[] =
2217"plock(op) -> None\n\
2218Lock program segments into memory.";
2219
Barry Warsaw53699e91996-12-10 23:23:01 +00002220static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002221posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002222{
2223 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002224 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002225 return NULL;
2226 if (plock(op) == -1)
2227 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002228 Py_INCREF(Py_None);
2229 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002230}
2231#endif
2232
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002233
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002234#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002235static char posix_popen__doc__[] =
2236"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2237Open a pipe to/from a command returning a file object.";
2238
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002239#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002240static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002241async_system(const char *command)
2242{
2243 char *p, errormsg[256], args[1024];
2244 RESULTCODES rcodes;
2245 APIRET rc;
2246 char *shell = getenv("COMSPEC");
2247 if (!shell)
2248 shell = "cmd";
2249
2250 strcpy(args, shell);
2251 p = &args[ strlen(args)+1 ];
2252 strcpy(p, "/c ");
2253 strcat(p, command);
2254 p += strlen(p) + 1;
2255 *p = '\0';
2256
2257 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002258 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002259 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002260 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002261 &rcodes, shell);
2262 return rc;
2263}
2264
Guido van Rossumd48f2521997-12-05 22:19:34 +00002265static FILE *
2266popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002267{
2268 HFILE rhan, whan;
2269 FILE *retfd = NULL;
2270 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2271
Guido van Rossumd48f2521997-12-05 22:19:34 +00002272 if (rc != NO_ERROR) {
2273 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002274 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002275 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002276
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002277 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2278 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002279
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002280 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2281 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002282
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002283 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2284 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002285
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002286 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002287 }
2288
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002289 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2290 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002291
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002292 if (rc == NO_ERROR)
2293 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2294
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002295 close(oldfd); /* And Close Saved STDOUT Handle */
2296 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002297
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002298 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2299 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002300
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002301 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2302 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002303
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002304 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2305 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002306
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002307 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002308 }
2309
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002310 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2311 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002312
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002313 if (rc == NO_ERROR)
2314 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2315
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002316 close(oldfd); /* And Close Saved STDIN Handle */
2317 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002318
Guido van Rossumd48f2521997-12-05 22:19:34 +00002319 } else {
2320 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002321 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002322 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002323}
2324
2325static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002326posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002327{
2328 char *name;
2329 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002330 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002331 FILE *fp;
2332 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002333 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002334 return NULL;
2335 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002336 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002337 Py_END_ALLOW_THREADS
2338 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002339 return os2_error(err);
2340
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002341 f = PyFile_FromFile(fp, name, mode, fclose);
2342 if (f != NULL)
2343 PyFile_SetBufSize(f, bufsize);
2344 return f;
2345}
2346
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002347#elif defined(MS_WIN32)
2348
2349/*
2350 * Portable 'popen' replacement for Win32.
2351 *
2352 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2353 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00002354 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002355 */
2356
2357#include <malloc.h>
2358#include <io.h>
2359#include <fcntl.h>
2360
2361/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2362#define POPEN_1 1
2363#define POPEN_2 2
2364#define POPEN_3 3
2365#define POPEN_4 4
2366
2367static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002368static int _PyPclose(FILE *file);
2369
2370/*
2371 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00002372 * for use when retrieving the process exit code. See _PyPclose() below
2373 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002374 */
2375static PyObject *_PyPopenProcs = NULL;
2376
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002377
2378/* popen that works from a GUI.
2379 *
2380 * The result of this function is a pipe (file) connected to the
2381 * processes stdin or stdout, depending on the requested mode.
2382 */
2383
2384static PyObject *
2385posix_popen(PyObject *self, PyObject *args)
2386{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002387 PyObject *f, *s;
2388 int tm = 0;
2389
2390 char *cmdstring;
2391 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002392 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002393 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002394 return NULL;
2395
2396 s = PyTuple_New(0);
2397
2398 if (*mode == 'r')
2399 tm = _O_RDONLY;
2400 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00002401 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002402 return NULL;
2403 } else
2404 tm = _O_WRONLY;
2405
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002406 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002407 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002408 return NULL;
2409 }
2410
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002411 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002412 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002413 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002414 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002415 else
2416 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2417
2418 return f;
2419}
2420
2421/* Variation on win32pipe.popen
2422 *
2423 * The result of this function is a pipe (file) connected to the
2424 * process's stdin, and a pipe connected to the process's stdout.
2425 */
2426
2427static PyObject *
2428win32_popen2(PyObject *self, PyObject *args)
2429{
2430 PyObject *f;
2431 int tm=0;
2432
2433 char *cmdstring;
2434 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002435 int bufsize = -1;
2436 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002437 return NULL;
2438
2439 if (*mode == 't')
2440 tm = _O_TEXT;
2441 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002442 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002443 return NULL;
2444 } else
2445 tm = _O_BINARY;
2446
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002447 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002448 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002449 return NULL;
2450 }
2451
2452 f = _PyPopen(cmdstring, tm, POPEN_2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002453
2454 return f;
2455}
2456
2457/*
2458 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002459 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002460 * The result of this function is 3 pipes - the process's stdin,
2461 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002462 */
2463
2464static PyObject *
2465win32_popen3(PyObject *self, PyObject *args)
2466{
2467 PyObject *f;
2468 int tm = 0;
2469
2470 char *cmdstring;
2471 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002472 int bufsize = -1;
2473 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002474 return NULL;
2475
2476 if (*mode == 't')
2477 tm = _O_TEXT;
2478 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002479 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002480 return NULL;
2481 } else
2482 tm = _O_BINARY;
2483
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002484 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002485 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002486 return NULL;
2487 }
2488
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002489 f = _PyPopen(cmdstring, tm, POPEN_3);
2490
2491 return f;
2492}
2493
2494/*
2495 * Variation on win32pipe.popen
2496 *
2497 * The result of this function is 2 pipes - the processes stdin,
2498 * and stdout+stderr combined as a single pipe.
2499 */
2500
2501static PyObject *
2502win32_popen4(PyObject *self, PyObject *args)
2503{
2504 PyObject *f;
2505 int tm = 0;
2506
2507 char *cmdstring;
2508 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002509 int bufsize = -1;
2510 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002511 return NULL;
2512
2513 if (*mode == 't')
2514 tm = _O_TEXT;
2515 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002516 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002517 return NULL;
2518 } else
2519 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002520
2521 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002522 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002523 return NULL;
2524 }
2525
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002526 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002527
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002528 return f;
2529}
2530
Mark Hammond08501372001-01-31 07:30:29 +00002531static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00002532_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002533 HANDLE hStdin,
2534 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00002535 HANDLE hStderr,
2536 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002537{
2538 PROCESS_INFORMATION piProcInfo;
2539 STARTUPINFO siStartInfo;
2540 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00002541 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002542 int i;
2543 int x;
2544
2545 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00002546 char *comshell;
2547
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002548 s1 = (char *)_alloca(i);
2549 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2550 return x;
Tim Peters402d5982001-08-27 06:37:48 +00002551
2552 /* Explicitly check if we are using COMMAND.COM. If we are
2553 * then use the w9xpopen hack.
2554 */
2555 comshell = s1 + x;
2556 while (comshell >= s1 && *comshell != '\\')
2557 --comshell;
2558 ++comshell;
2559
2560 if (GetVersion() < 0x80000000 &&
2561 _stricmp(comshell, "command.com") != 0) {
2562 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002563 x = i + strlen(s3) + strlen(cmdstring) + 1;
2564 s2 = (char *)_alloca(x);
2565 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00002566 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002567 }
2568 else {
2569 /*
Tim Peters402d5982001-08-27 06:37:48 +00002570 * Oh gag, we're on Win9x or using COMMAND.COM. Use
2571 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002572 */
Mark Hammond08501372001-01-31 07:30:29 +00002573 char modulepath[_MAX_PATH];
2574 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002575 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2576 for (i = x = 0; modulepath[i]; i++)
2577 if (modulepath[i] == '\\')
2578 x = i+1;
2579 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00002580 /* Create the full-name to w9xpopen, so we can test it exists */
2581 strncat(modulepath,
2582 szConsoleSpawn,
2583 (sizeof(modulepath)/sizeof(modulepath[0]))
2584 -strlen(modulepath));
2585 if (stat(modulepath, &statinfo) != 0) {
2586 /* Eeek - file-not-found - possibly an embedding
2587 situation - see if we can locate it in sys.prefix
2588 */
2589 strncpy(modulepath,
2590 Py_GetExecPrefix(),
2591 sizeof(modulepath)/sizeof(modulepath[0]));
2592 if (modulepath[strlen(modulepath)-1] != '\\')
2593 strcat(modulepath, "\\");
2594 strncat(modulepath,
2595 szConsoleSpawn,
2596 (sizeof(modulepath)/sizeof(modulepath[0]))
2597 -strlen(modulepath));
2598 /* No where else to look - raise an easily identifiable
2599 error, rather than leaving Windows to report
2600 "file not found" - as the user is probably blissfully
2601 unaware this shim EXE is used, and it will confuse them.
2602 (well, it confused me for a while ;-)
2603 */
2604 if (stat(modulepath, &statinfo) != 0) {
2605 PyErr_Format(PyExc_RuntimeError,
2606 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00002607 "for popen to work with your shell "
2608 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00002609 szConsoleSpawn);
2610 return FALSE;
2611 }
2612 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002613 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2614 strlen(modulepath) +
2615 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00002616
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002617 s2 = (char *)_alloca(x);
2618 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00002619 PyOS_snprintf(
2620 s2, x,
Mark Hammond08501372001-01-31 07:30:29 +00002621 "%s \"%s%s%s\"",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002622 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002623 s1,
2624 s3,
2625 cmdstring);
2626 }
2627 }
2628
2629 /* Could be an else here to try cmd.exe / command.com in the path
2630 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00002631 else {
Tim Peters402d5982001-08-27 06:37:48 +00002632 PyErr_SetString(PyExc_RuntimeError,
2633 "Cannot locate a COMSPEC environment variable to "
2634 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00002635 return FALSE;
2636 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002637
2638 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2639 siStartInfo.cb = sizeof(STARTUPINFO);
2640 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2641 siStartInfo.hStdInput = hStdin;
2642 siStartInfo.hStdOutput = hStdout;
2643 siStartInfo.hStdError = hStderr;
2644 siStartInfo.wShowWindow = SW_HIDE;
2645
2646 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002647 s2,
2648 NULL,
2649 NULL,
2650 TRUE,
2651 CREATE_NEW_CONSOLE,
2652 NULL,
2653 NULL,
2654 &siStartInfo,
2655 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002656 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002657 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002658
Mark Hammondb37a3732000-08-14 04:47:33 +00002659 /* Return process handle */
2660 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002661 return TRUE;
2662 }
Tim Peters402d5982001-08-27 06:37:48 +00002663 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002664 return FALSE;
2665}
2666
2667/* The following code is based off of KB: Q190351 */
2668
2669static PyObject *
2670_PyPopen(char *cmdstring, int mode, int n)
2671{
2672 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2673 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00002674 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002675
2676 SECURITY_ATTRIBUTES saAttr;
2677 BOOL fSuccess;
2678 int fd1, fd2, fd3;
2679 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00002680 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002681 PyObject *f;
2682
2683 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2684 saAttr.bInheritHandle = TRUE;
2685 saAttr.lpSecurityDescriptor = NULL;
2686
2687 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2688 return win32_error("CreatePipe", NULL);
2689
2690 /* Create new output read handle and the input write handle. Set
2691 * the inheritance properties to FALSE. Otherwise, the child inherits
2692 * the these handles; resulting in non-closeable handles to the pipes
2693 * being created. */
2694 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002695 GetCurrentProcess(), &hChildStdinWrDup, 0,
2696 FALSE,
2697 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002698 if (!fSuccess)
2699 return win32_error("DuplicateHandle", NULL);
2700
2701 /* Close the inheritable version of ChildStdin
2702 that we're using. */
2703 CloseHandle(hChildStdinWr);
2704
2705 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2706 return win32_error("CreatePipe", NULL);
2707
2708 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002709 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2710 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002711 if (!fSuccess)
2712 return win32_error("DuplicateHandle", NULL);
2713
2714 /* Close the inheritable version of ChildStdout
2715 that we're using. */
2716 CloseHandle(hChildStdoutRd);
2717
2718 if (n != POPEN_4) {
2719 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2720 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002721 fSuccess = DuplicateHandle(GetCurrentProcess(),
2722 hChildStderrRd,
2723 GetCurrentProcess(),
2724 &hChildStderrRdDup, 0,
2725 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002726 if (!fSuccess)
2727 return win32_error("DuplicateHandle", NULL);
2728 /* Close the inheritable version of ChildStdErr that we're using. */
2729 CloseHandle(hChildStderrRd);
2730 }
2731
2732 switch (n) {
2733 case POPEN_1:
2734 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2735 case _O_WRONLY | _O_TEXT:
2736 /* Case for writing to child Stdin in text mode. */
2737 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2738 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002739 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002740 PyFile_SetBufSize(f, 0);
2741 /* We don't care about these pipes anymore, so close them. */
2742 CloseHandle(hChildStdoutRdDup);
2743 CloseHandle(hChildStderrRdDup);
2744 break;
2745
2746 case _O_RDONLY | _O_TEXT:
2747 /* Case for reading from child Stdout in text mode. */
2748 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2749 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002750 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002751 PyFile_SetBufSize(f, 0);
2752 /* We don't care about these pipes anymore, so close them. */
2753 CloseHandle(hChildStdinWrDup);
2754 CloseHandle(hChildStderrRdDup);
2755 break;
2756
2757 case _O_RDONLY | _O_BINARY:
2758 /* Case for readinig from child Stdout in binary mode. */
2759 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2760 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002761 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002762 PyFile_SetBufSize(f, 0);
2763 /* We don't care about these pipes anymore, so close them. */
2764 CloseHandle(hChildStdinWrDup);
2765 CloseHandle(hChildStderrRdDup);
2766 break;
2767
2768 case _O_WRONLY | _O_BINARY:
2769 /* Case for writing to child Stdin in binary mode. */
2770 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2771 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002772 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002773 PyFile_SetBufSize(f, 0);
2774 /* We don't care about these pipes anymore, so close them. */
2775 CloseHandle(hChildStdoutRdDup);
2776 CloseHandle(hChildStderrRdDup);
2777 break;
2778 }
Mark Hammondb37a3732000-08-14 04:47:33 +00002779 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002780 break;
2781
2782 case POPEN_2:
2783 case POPEN_4:
2784 {
2785 char *m1, *m2;
2786 PyObject *p1, *p2;
2787
2788 if (mode && _O_TEXT) {
2789 m1 = "r";
2790 m2 = "w";
2791 } else {
2792 m1 = "rb";
2793 m2 = "wb";
2794 }
2795
2796 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2797 f1 = _fdopen(fd1, m2);
2798 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2799 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002800 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002801 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00002802 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002803 PyFile_SetBufSize(p2, 0);
2804
2805 if (n != 4)
2806 CloseHandle(hChildStderrRdDup);
2807
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002808 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00002809 Py_XDECREF(p1);
2810 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00002811 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002812 break;
2813 }
2814
2815 case POPEN_3:
2816 {
2817 char *m1, *m2;
2818 PyObject *p1, *p2, *p3;
2819
2820 if (mode && _O_TEXT) {
2821 m1 = "r";
2822 m2 = "w";
2823 } else {
2824 m1 = "rb";
2825 m2 = "wb";
2826 }
2827
2828 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2829 f1 = _fdopen(fd1, m2);
2830 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2831 f2 = _fdopen(fd2, m1);
2832 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2833 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002834 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00002835 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
2836 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002837 PyFile_SetBufSize(p1, 0);
2838 PyFile_SetBufSize(p2, 0);
2839 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002840 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00002841 Py_XDECREF(p1);
2842 Py_XDECREF(p2);
2843 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00002844 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002845 break;
2846 }
2847 }
2848
2849 if (n == POPEN_4) {
2850 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002851 hChildStdinRd,
2852 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002853 hChildStdoutWr,
2854 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002855 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002856 }
2857 else {
2858 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002859 hChildStdinRd,
2860 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002861 hChildStderrWr,
2862 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002863 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002864 }
2865
Mark Hammondb37a3732000-08-14 04:47:33 +00002866 /*
2867 * Insert the files we've created into the process dictionary
2868 * all referencing the list with the process handle and the
2869 * initial number of files (see description below in _PyPclose).
2870 * Since if _PyPclose later tried to wait on a process when all
2871 * handles weren't closed, it could create a deadlock with the
2872 * child, we spend some energy here to try to ensure that we
2873 * either insert all file handles into the dictionary or none
2874 * at all. It's a little clumsy with the various popen modes
2875 * and variable number of files involved.
2876 */
2877 if (!_PyPopenProcs) {
2878 _PyPopenProcs = PyDict_New();
2879 }
2880
2881 if (_PyPopenProcs) {
2882 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
2883 int ins_rc[3];
2884
2885 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2886 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2887
2888 procObj = PyList_New(2);
2889 hProcessObj = PyLong_FromVoidPtr(hProcess);
2890 intObj = PyInt_FromLong(file_count);
2891
2892 if (procObj && hProcessObj && intObj) {
2893 PyList_SetItem(procObj,0,hProcessObj);
2894 PyList_SetItem(procObj,1,intObj);
2895
2896 fileObj[0] = PyLong_FromVoidPtr(f1);
2897 if (fileObj[0]) {
2898 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2899 fileObj[0],
2900 procObj);
2901 }
2902 if (file_count >= 2) {
2903 fileObj[1] = PyLong_FromVoidPtr(f2);
2904 if (fileObj[1]) {
2905 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2906 fileObj[1],
2907 procObj);
2908 }
2909 }
2910 if (file_count >= 3) {
2911 fileObj[2] = PyLong_FromVoidPtr(f3);
2912 if (fileObj[2]) {
2913 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2914 fileObj[2],
2915 procObj);
2916 }
2917 }
2918
2919 if (ins_rc[0] < 0 || !fileObj[0] ||
2920 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2921 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
2922 /* Something failed - remove any dictionary
2923 * entries that did make it.
2924 */
2925 if (!ins_rc[0] && fileObj[0]) {
2926 PyDict_DelItem(_PyPopenProcs,
2927 fileObj[0]);
2928 }
2929 if (!ins_rc[1] && fileObj[1]) {
2930 PyDict_DelItem(_PyPopenProcs,
2931 fileObj[1]);
2932 }
2933 if (!ins_rc[2] && fileObj[2]) {
2934 PyDict_DelItem(_PyPopenProcs,
2935 fileObj[2]);
2936 }
2937 }
2938 }
2939
2940 /*
2941 * Clean up our localized references for the dictionary keys
2942 * and value since PyDict_SetItem will Py_INCREF any copies
2943 * that got placed in the dictionary.
2944 */
2945 Py_XDECREF(procObj);
2946 Py_XDECREF(fileObj[0]);
2947 Py_XDECREF(fileObj[1]);
2948 Py_XDECREF(fileObj[2]);
2949 }
2950
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002951 /* Child is launched. Close the parents copy of those pipe
2952 * handles that only the child should have open. You need to
2953 * make sure that no handles to the write end of the output pipe
2954 * are maintained in this process or else the pipe will not close
2955 * when the child process exits and the ReadFile will hang. */
2956
2957 if (!CloseHandle(hChildStdinRd))
2958 return win32_error("CloseHandle", NULL);
2959
2960 if (!CloseHandle(hChildStdoutWr))
2961 return win32_error("CloseHandle", NULL);
2962
2963 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2964 return win32_error("CloseHandle", NULL);
2965
2966 return f;
2967}
Fredrik Lundh56055a42000-07-23 19:47:12 +00002968
2969/*
2970 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2971 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00002972 *
2973 * This function uses the _PyPopenProcs dictionary in order to map the
2974 * input file pointer to information about the process that was
2975 * originally created by the popen* call that created the file pointer.
2976 * The dictionary uses the file pointer as a key (with one entry
2977 * inserted for each file returned by the original popen* call) and a
2978 * single list object as the value for all files from a single call.
2979 * The list object contains the Win32 process handle at [0], and a file
2980 * count at [1], which is initialized to the total number of file
2981 * handles using that list.
2982 *
2983 * This function closes whichever handle it is passed, and decrements
2984 * the file count in the dictionary for the process handle pointed to
2985 * by this file. On the last close (when the file count reaches zero),
2986 * this function will wait for the child process and then return its
2987 * exit code as the result of the close() operation. This permits the
2988 * files to be closed in any order - it is always the close() of the
2989 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002990 */
Tim Peters736aa322000-09-01 06:51:24 +00002991
2992 /* RED_FLAG 31-Aug-2000 Tim
2993 * This is always called (today!) between a pair of
2994 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2995 * macros. So the thread running this has no valid thread state, as
2996 * far as Python is concerned. However, this calls some Python API
2997 * functions that cannot be called safely without a valid thread
2998 * state, in particular PyDict_GetItem.
2999 * As a temporary hack (although it may last for years ...), we
3000 * *rely* on not having a valid thread state in this function, in
3001 * order to create our own "from scratch".
3002 * This will deadlock if _PyPclose is ever called by a thread
3003 * holding the global lock.
3004 */
3005
Fredrik Lundh56055a42000-07-23 19:47:12 +00003006static int _PyPclose(FILE *file)
3007{
Fredrik Lundh20318932000-07-26 17:29:12 +00003008 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003009 DWORD exit_code;
3010 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00003011 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
3012 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00003013#ifdef WITH_THREAD
3014 PyInterpreterState* pInterpreterState;
3015 PyThreadState* pThreadState;
3016#endif
3017
Fredrik Lundh20318932000-07-26 17:29:12 +00003018 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00003019 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00003020 */
3021 result = fclose(file);
3022
Tim Peters736aa322000-09-01 06:51:24 +00003023#ifdef WITH_THREAD
3024 /* Bootstrap a valid thread state into existence. */
3025 pInterpreterState = PyInterpreterState_New();
3026 if (!pInterpreterState) {
3027 /* Well, we're hosed now! We don't have a thread
3028 * state, so can't call a nice error routine, or raise
3029 * an exception. Just die.
3030 */
3031 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00003032 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003033 return -1; /* unreachable */
3034 }
3035 pThreadState = PyThreadState_New(pInterpreterState);
3036 if (!pThreadState) {
3037 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00003038 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003039 return -1; /* unreachable */
3040 }
3041 /* Grab the global lock. Note that this will deadlock if the
3042 * current thread already has the lock! (see RED_FLAG comments
3043 * before this function)
3044 */
3045 PyEval_RestoreThread(pThreadState);
3046#endif
3047
Fredrik Lundh56055a42000-07-23 19:47:12 +00003048 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00003049 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3050 (procObj = PyDict_GetItem(_PyPopenProcs,
3051 fileObj)) != NULL &&
3052 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
3053 (intObj = PyList_GetItem(procObj,1)) != NULL) {
3054
3055 hProcess = PyLong_AsVoidPtr(hProcessObj);
3056 file_count = PyInt_AsLong(intObj);
3057
3058 if (file_count > 1) {
3059 /* Still other files referencing process */
3060 file_count--;
3061 PyList_SetItem(procObj,1,
3062 PyInt_FromLong(file_count));
3063 } else {
3064 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00003065 if (result != EOF &&
3066 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
3067 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00003068 /* Possible truncation here in 16-bit environments, but
3069 * real exit codes are just the lower byte in any event.
3070 */
3071 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003072 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00003073 /* Indicate failure - this will cause the file object
3074 * to raise an I/O error and translate the last Win32
3075 * error code from errno. We do have a problem with
3076 * last errors that overlap the normal errno table,
3077 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003078 */
Fredrik Lundh20318932000-07-26 17:29:12 +00003079 if (result != EOF) {
3080 /* If the error wasn't from the fclose(), then
3081 * set errno for the file object error handling.
3082 */
3083 errno = GetLastError();
3084 }
3085 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003086 }
3087
3088 /* Free up the native handle at this point */
3089 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00003090 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00003091
Mark Hammondb37a3732000-08-14 04:47:33 +00003092 /* Remove this file pointer from dictionary */
3093 PyDict_DelItem(_PyPopenProcs, fileObj);
3094
3095 if (PyDict_Size(_PyPopenProcs) == 0) {
3096 Py_DECREF(_PyPopenProcs);
3097 _PyPopenProcs = NULL;
3098 }
3099
3100 } /* if object retrieval ok */
3101
3102 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003103 } /* if _PyPopenProcs */
3104
Tim Peters736aa322000-09-01 06:51:24 +00003105#ifdef WITH_THREAD
3106 /* Tear down the thread & interpreter states.
3107 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00003108 * call the thread clear & delete functions, and indeed insist on
3109 * doing that themselves. The lock must be held during the clear, but
3110 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00003111 */
3112 PyInterpreterState_Clear(pInterpreterState);
3113 PyEval_ReleaseThread(pThreadState);
3114 PyInterpreterState_Delete(pInterpreterState);
3115#endif
3116
Fredrik Lundh56055a42000-07-23 19:47:12 +00003117 return result;
3118}
Tim Peters9acdd3a2000-09-01 19:26:36 +00003119
3120#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00003121static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003122posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00003123{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003124 char *name;
3125 char *mode = "r";
3126 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00003127 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003128 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003129 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00003130 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003131 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003132 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003133 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00003134 if (fp == NULL)
3135 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003136 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003137 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003138 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003139 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00003140}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003141#endif
3142
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003143#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00003144
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003145
Guido van Rossumb6775db1994-08-01 11:34:53 +00003146#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003147static char posix_setuid__doc__[] =
3148"setuid(uid) -> None\n\
3149Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00003150static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003151posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003152{
3153 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003154 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003155 return NULL;
3156 if (setuid(uid) < 0)
3157 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003158 Py_INCREF(Py_None);
3159 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003160}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003161#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003162
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003163
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003164#ifdef HAVE_SETEUID
3165static char posix_seteuid__doc__[] =
3166"seteuid(uid) -> None\n\
3167Set the current process's effective user id.";
3168static PyObject *
3169posix_seteuid (PyObject *self, PyObject *args)
3170{
3171 int euid;
3172 if (!PyArg_ParseTuple(args, "i", &euid)) {
3173 return NULL;
3174 } else if (seteuid(euid) < 0) {
3175 return posix_error();
3176 } else {
3177 Py_INCREF(Py_None);
3178 return Py_None;
3179 }
3180}
3181#endif /* HAVE_SETEUID */
3182
3183#ifdef HAVE_SETEGID
3184static char posix_setegid__doc__[] =
3185"setegid(gid) -> None\n\
3186Set the current process's effective group id.";
3187static PyObject *
3188posix_setegid (PyObject *self, PyObject *args)
3189{
3190 int egid;
3191 if (!PyArg_ParseTuple(args, "i", &egid)) {
3192 return NULL;
3193 } else if (setegid(egid) < 0) {
3194 return posix_error();
3195 } else {
3196 Py_INCREF(Py_None);
3197 return Py_None;
3198 }
3199}
3200#endif /* HAVE_SETEGID */
3201
3202#ifdef HAVE_SETREUID
3203static char posix_setreuid__doc__[] =
3204"seteuid(ruid, euid) -> None\n\
3205Set the current process's real and effective user ids.";
3206static PyObject *
3207posix_setreuid (PyObject *self, PyObject *args)
3208{
3209 int ruid, euid;
3210 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3211 return NULL;
3212 } else if (setreuid(ruid, euid) < 0) {
3213 return posix_error();
3214 } else {
3215 Py_INCREF(Py_None);
3216 return Py_None;
3217 }
3218}
3219#endif /* HAVE_SETREUID */
3220
3221#ifdef HAVE_SETREGID
3222static char posix_setregid__doc__[] =
3223"setegid(rgid, egid) -> None\n\
3224Set the current process's real and effective group ids.";
3225static PyObject *
3226posix_setregid (PyObject *self, PyObject *args)
3227{
3228 int rgid, egid;
3229 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3230 return NULL;
3231 } else if (setregid(rgid, egid) < 0) {
3232 return posix_error();
3233 } else {
3234 Py_INCREF(Py_None);
3235 return Py_None;
3236 }
3237}
3238#endif /* HAVE_SETREGID */
3239
Guido van Rossumb6775db1994-08-01 11:34:53 +00003240#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003241static char posix_setgid__doc__[] =
3242"setgid(gid) -> None\n\
3243Set the current process's group id.";
3244
Barry Warsaw53699e91996-12-10 23:23:01 +00003245static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003246posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003247{
3248 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003249 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003250 return NULL;
3251 if (setgid(gid) < 0)
3252 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003253 Py_INCREF(Py_None);
3254 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003255}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003256#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003257
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003258#ifdef HAVE_SETGROUPS
3259static char posix_setgroups__doc__[] =
3260"setgroups(list) -> None\n\
3261Set the groups of the current process to list.";
3262
3263static PyObject *
3264posix_setgroups(PyObject *self, PyObject *args)
3265{
3266 PyObject *groups;
3267 int i, len;
3268 gid_t grouplist[MAX_GROUPS];
3269
3270 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
3271 return NULL;
3272 if (!PySequence_Check(groups)) {
3273 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
3274 return NULL;
3275 }
3276 len = PySequence_Size(groups);
3277 if (len > MAX_GROUPS) {
3278 PyErr_SetString(PyExc_ValueError, "too many groups");
3279 return NULL;
3280 }
3281 for(i = 0; i < len; i++) {
3282 PyObject *elem;
3283 elem = PySequence_GetItem(groups, i);
3284 if (!elem)
3285 return NULL;
3286 if (!PyInt_Check(elem)) {
3287 PyErr_SetString(PyExc_TypeError,
3288 "groups must be integers");
3289 Py_DECREF(elem);
3290 return NULL;
3291 }
3292 /* XXX: check that value fits into gid_t. */
3293 grouplist[i] = PyInt_AsLong(elem);
3294 Py_DECREF(elem);
3295 }
3296
3297 if (setgroups(len, grouplist) < 0)
3298 return posix_error();
3299 Py_INCREF(Py_None);
3300 return Py_None;
3301}
3302#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003303
Guido van Rossumb6775db1994-08-01 11:34:53 +00003304#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003305static char posix_waitpid__doc__[] =
3306"waitpid(pid, options) -> (pid, status)\n\
Guido van Rossumf377d572000-12-12 00:37:58 +00003307Wait for completion of a given child process.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003308
Barry Warsaw53699e91996-12-10 23:23:01 +00003309static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003310posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003311{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003312 int pid, options;
3313#ifdef UNION_WAIT
3314 union wait status;
3315#define status_i (status.w_status)
3316#else
3317 int status;
3318#define status_i status
3319#endif
3320 status_i = 0;
3321
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003322 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00003323 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003324 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003325#ifdef NeXT
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003326 pid = wait4(pid, &status, options, NULL);
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003327#else
3328 pid = waitpid(pid, &status, options);
3329#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003330 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00003331 if (pid == -1)
3332 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00003333 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003334 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00003335}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003336#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +00003337
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003338
Guido van Rossumad0ee831995-03-01 10:34:45 +00003339#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003340static char posix_wait__doc__[] =
3341"wait() -> (pid, status)\n\
3342Wait for completion of a child process.";
3343
Barry Warsaw53699e91996-12-10 23:23:01 +00003344static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003345posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00003346{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003347 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003348#ifdef UNION_WAIT
3349 union wait status;
3350#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003351#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003352 int status;
3353#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003354#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003355 if (!PyArg_ParseTuple(args, ":wait"))
3356 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003357 status_i = 0;
3358 Py_BEGIN_ALLOW_THREADS
3359 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00003360 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00003361 if (pid == -1)
3362 return posix_error();
3363 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003364 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003365#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00003366}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003367#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003368
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003369
3370static char posix_lstat__doc__[] =
3371"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
3372Like stat(path), but do not follow symbolic links.";
3373
Barry Warsaw53699e91996-12-10 23:23:01 +00003374static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003375posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003376{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003377#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00003378 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003379#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00003380 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003381#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003382}
3383
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003384
Guido van Rossumb6775db1994-08-01 11:34:53 +00003385#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003386static char posix_readlink__doc__[] =
3387"readlink(path) -> path\n\
3388Return a string representing the path to which the symbolic link points.";
3389
Barry Warsaw53699e91996-12-10 23:23:01 +00003390static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003391posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003392{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003393 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003394 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003395 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003396 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003397 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003398 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00003399 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00003400 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003401 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003402 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00003403 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003404}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003405#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003406
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003407
Guido van Rossumb6775db1994-08-01 11:34:53 +00003408#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003409static char posix_symlink__doc__[] =
3410"symlink(src, dst) -> None\n\
3411Create a symbolic link.";
3412
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003413static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003414posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003415{
Mark Hammondef8b6542001-05-13 08:04:26 +00003416 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003417}
3418#endif /* HAVE_SYMLINK */
3419
3420
3421#ifdef HAVE_TIMES
3422#ifndef HZ
3423#define HZ 60 /* Universal constant :-) */
3424#endif /* HZ */
3425
Guido van Rossumd48f2521997-12-05 22:19:34 +00003426#if defined(PYCC_VACPP) && defined(PYOS_OS2)
3427static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003428system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003429{
3430 ULONG value = 0;
3431
3432 Py_BEGIN_ALLOW_THREADS
3433 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
3434 Py_END_ALLOW_THREADS
3435
3436 return value;
3437}
3438
3439static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003440posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003441{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003442 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00003443 return NULL;
3444
3445 /* Currently Only Uptime is Provided -- Others Later */
3446 return Py_BuildValue("ddddd",
3447 (double)0 /* t.tms_utime / HZ */,
3448 (double)0 /* t.tms_stime / HZ */,
3449 (double)0 /* t.tms_cutime / HZ */,
3450 (double)0 /* t.tms_cstime / HZ */,
3451 (double)system_uptime() / 1000);
3452}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003453#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003454static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003455posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00003456{
3457 struct tms t;
3458 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003459 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00003460 return NULL;
3461 errno = 0;
3462 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00003463 if (c == (clock_t) -1)
3464 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003465 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00003466 (double)t.tms_utime / HZ,
3467 (double)t.tms_stime / HZ,
3468 (double)t.tms_cutime / HZ,
3469 (double)t.tms_cstime / HZ,
3470 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00003471}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003472#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003473#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003474
3475
Guido van Rossum87755a21996-09-07 00:59:43 +00003476#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003477#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00003478static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003479posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003480{
3481 FILETIME create, exit, kernel, user;
3482 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003483 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003484 return NULL;
3485 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003486 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
3487 /* The fields of a FILETIME structure are the hi and lo part
3488 of a 64-bit value expressed in 100 nanosecond units.
3489 1e7 is one second in such units; 1e-7 the inverse.
3490 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
3491 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003492 return Py_BuildValue(
3493 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003494 (double)(kernel.dwHighDateTime*429.4967296 +
3495 kernel.dwLowDateTime*1e-7),
3496 (double)(user.dwHighDateTime*429.4967296 +
3497 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00003498 (double)0,
3499 (double)0,
3500 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003501}
Guido van Rossum8d665e61996-06-26 18:22:49 +00003502#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003503
3504#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00003505static char posix_times__doc__[] =
3506"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
3507Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003508#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003509
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003510
Guido van Rossumb6775db1994-08-01 11:34:53 +00003511#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003512static char posix_setsid__doc__[] =
3513"setsid() -> None\n\
3514Call the system call setsid().";
3515
Barry Warsaw53699e91996-12-10 23:23:01 +00003516static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003517posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003518{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003519 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003520 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003521 if (setsid() < 0)
3522 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003523 Py_INCREF(Py_None);
3524 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003525}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003526#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003527
Guido van Rossumb6775db1994-08-01 11:34:53 +00003528#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003529static char posix_setpgid__doc__[] =
3530"setpgid(pid, pgrp) -> None\n\
3531Call the system call setpgid().";
3532
Barry Warsaw53699e91996-12-10 23:23:01 +00003533static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003534posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003535{
3536 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003537 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003538 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003539 if (setpgid(pid, pgrp) < 0)
3540 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003541 Py_INCREF(Py_None);
3542 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003543}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003544#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003545
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003546
Guido van Rossumb6775db1994-08-01 11:34:53 +00003547#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003548static char posix_tcgetpgrp__doc__[] =
3549"tcgetpgrp(fd) -> pgid\n\
3550Return the process group associated with the terminal given by a fd.";
3551
Barry Warsaw53699e91996-12-10 23:23:01 +00003552static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003553posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003554{
3555 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003556 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003557 return NULL;
3558 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003559 if (pgid < 0)
3560 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003561 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00003562}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003563#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00003564
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003565
Guido van Rossumb6775db1994-08-01 11:34:53 +00003566#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003567static char posix_tcsetpgrp__doc__[] =
3568"tcsetpgrp(fd, pgid) -> None\n\
3569Set the process group associated with the terminal given by a fd.";
3570
Barry Warsaw53699e91996-12-10 23:23:01 +00003571static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003572posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003573{
3574 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003575 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003576 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003577 if (tcsetpgrp(fd, pgid) < 0)
3578 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00003579 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00003580 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00003581}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003582#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00003583
Guido van Rossum687dd131993-05-17 08:34:16 +00003584/* Functions acting on file descriptors */
3585
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003586static char posix_open__doc__[] =
3587"open(filename, flag [, mode=0777]) -> fd\n\
3588Open a file (for low level IO).";
3589
Barry Warsaw53699e91996-12-10 23:23:01 +00003590static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003591posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003592{
Mark Hammondef8b6542001-05-13 08:04:26 +00003593 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003594 int flag;
3595 int mode = 0777;
3596 int fd;
Mark Hammondef8b6542001-05-13 08:04:26 +00003597 if (!PyArg_ParseTuple(args, "eti|i",
3598 Py_FileSystemDefaultEncoding, &file,
3599 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003600 return NULL;
3601
Barry Warsaw53699e91996-12-10 23:23:01 +00003602 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003603 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003604 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003605 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00003606 return posix_error_with_allocated_filename(file);
3607 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00003608 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003609}
3610
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003611
3612static char posix_close__doc__[] =
3613"close(fd) -> None\n\
3614Close a file descriptor (for low level IO).";
3615
Barry Warsaw53699e91996-12-10 23:23:01 +00003616static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003617posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003618{
3619 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003620 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003621 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003622 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003623 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003624 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003625 if (res < 0)
3626 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003627 Py_INCREF(Py_None);
3628 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003629}
3630
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003631
3632static char posix_dup__doc__[] =
3633"dup(fd) -> fd2\n\
3634Return a duplicate of a file descriptor.";
3635
Barry Warsaw53699e91996-12-10 23:23:01 +00003636static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003637posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003638{
3639 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003640 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003641 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003642 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003643 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003644 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003645 if (fd < 0)
3646 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003647 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003648}
3649
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003650
3651static char posix_dup2__doc__[] =
3652"dup2(fd, fd2) -> None\n\
3653Duplicate file descriptor.";
3654
Barry Warsaw53699e91996-12-10 23:23:01 +00003655static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003656posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003657{
3658 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003659 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00003660 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003661 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003662 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00003663 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003664 if (res < 0)
3665 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003666 Py_INCREF(Py_None);
3667 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003668}
3669
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003670
3671static char posix_lseek__doc__[] =
3672"lseek(fd, pos, how) -> newpos\n\
3673Set the current position of a file descriptor.";
3674
Barry Warsaw53699e91996-12-10 23:23:01 +00003675static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003676posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003677{
3678 int fd, how;
Tim Peters6e13a562001-09-06 00:32:15 +00003679#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00003680 LONG_LONG pos, res;
3681#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003682 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003683#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003684 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003685 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003686 return NULL;
3687#ifdef SEEK_SET
3688 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3689 switch (how) {
3690 case 0: how = SEEK_SET; break;
3691 case 1: how = SEEK_CUR; break;
3692 case 2: how = SEEK_END; break;
3693 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003694#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003695
3696#if !defined(HAVE_LARGEFILE_SUPPORT)
3697 pos = PyInt_AsLong(posobj);
3698#else
3699 pos = PyLong_Check(posobj) ?
3700 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3701#endif
3702 if (PyErr_Occurred())
3703 return NULL;
3704
Barry Warsaw53699e91996-12-10 23:23:01 +00003705 Py_BEGIN_ALLOW_THREADS
Tim Peters6e13a562001-09-06 00:32:15 +00003706#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00003707 res = _lseeki64(fd, pos, how);
3708#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003709 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003710#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003711 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003712 if (res < 0)
3713 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003714
3715#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003716 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003717#else
3718 return PyLong_FromLongLong(res);
3719#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003720}
3721
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003722
3723static char posix_read__doc__[] =
3724"read(fd, buffersize) -> string\n\
3725Read a file descriptor.";
3726
Barry Warsaw53699e91996-12-10 23:23:01 +00003727static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003728posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003729{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003730 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003731 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003732 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003733 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003734 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003735 if (buffer == NULL)
3736 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003737 Py_BEGIN_ALLOW_THREADS
3738 n = read(fd, PyString_AsString(buffer), size);
3739 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003740 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003741 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003742 return posix_error();
3743 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003744 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003745 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003746 return buffer;
3747}
3748
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003749
3750static char posix_write__doc__[] =
3751"write(fd, string) -> byteswritten\n\
3752Write a string to a file descriptor.";
3753
Barry Warsaw53699e91996-12-10 23:23:01 +00003754static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003755posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003756{
3757 int fd, size;
3758 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003759 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003760 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003761 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003762 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003763 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003764 if (size < 0)
3765 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003766 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003767}
3768
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003769
3770static char posix_fstat__doc__[]=
3771"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3772Like stat(), but for an open file descriptor.";
3773
Barry Warsaw53699e91996-12-10 23:23:01 +00003774static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003775posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003776{
3777 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003778 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003779 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003780 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003781 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003782 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003783 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003784 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003785 if (res != 0)
3786 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00003787
3788 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003789}
3790
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003791
3792static char posix_fdopen__doc__[] =
3793"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3794Return an open file object connected to a file descriptor.";
3795
Barry Warsaw53699e91996-12-10 23:23:01 +00003796static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003797posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003798{
Guido van Rossum687dd131993-05-17 08:34:16 +00003799 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003800 char *mode = "r";
3801 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003802 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003803 PyObject *f;
3804 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003805 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003806
Barry Warsaw53699e91996-12-10 23:23:01 +00003807 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003808 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003809 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003810 if (fp == NULL)
3811 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003812 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003813 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003814 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003815 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003816}
3817
Skip Montanaro1517d842000-07-19 14:34:14 +00003818static char posix_isatty__doc__[] =
3819"isatty(fd) -> Boolean\n\
3820Return true if the file descriptor 'fd' is an open file descriptor\n\
Thomas Wouters12e15952000-10-03 16:54:24 +00003821connected to the slave end of a terminal.";
Skip Montanaro1517d842000-07-19 14:34:14 +00003822
3823static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00003824posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00003825{
3826 int fd;
3827 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3828 return NULL;
3829 return Py_BuildValue("i", isatty(fd));
3830}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003831
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003832#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003833static char posix_pipe__doc__[] =
3834"pipe() -> (read_end, write_end)\n\
3835Create a pipe.";
3836
Barry Warsaw53699e91996-12-10 23:23:01 +00003837static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003838posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003839{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003840#if defined(PYOS_OS2)
3841 HFILE read, write;
3842 APIRET rc;
3843
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003844 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003845 return NULL;
3846
3847 Py_BEGIN_ALLOW_THREADS
3848 rc = DosCreatePipe( &read, &write, 4096);
3849 Py_END_ALLOW_THREADS
3850 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003851 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003852
3853 return Py_BuildValue("(ii)", read, write);
3854#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003855#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003856 int fds[2];
3857 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003858 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003859 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003860 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003861 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003862 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003863 if (res != 0)
3864 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003865 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003866#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003867 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003868 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003869 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003870 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003871 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003872 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003873 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003874 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003875 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003876 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00003877 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
3878 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003879 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003880#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003881#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003882}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003883#endif /* HAVE_PIPE */
3884
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003885
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003886#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003887static char posix_mkfifo__doc__[] =
3888"mkfifo(file, [, mode=0666]) -> None\n\
3889Create a FIFO (a POSIX named pipe).";
3890
Barry Warsaw53699e91996-12-10 23:23:01 +00003891static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003892posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003893{
3894 char *file;
3895 int mode = 0666;
3896 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003897 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003898 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003899 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003900 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003901 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003902 if (res < 0)
3903 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003904 Py_INCREF(Py_None);
3905 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003906}
3907#endif
3908
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003909
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003910#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003911static char posix_ftruncate__doc__[] =
3912"ftruncate(fd, length) -> None\n\
3913Truncate a file to a specified length.";
3914
Barry Warsaw53699e91996-12-10 23:23:01 +00003915static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003916posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003917{
3918 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003919 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003920 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003921 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003922
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003923 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003924 return NULL;
3925
3926#if !defined(HAVE_LARGEFILE_SUPPORT)
3927 length = PyInt_AsLong(lenobj);
3928#else
3929 length = PyLong_Check(lenobj) ?
3930 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3931#endif
3932 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003933 return NULL;
3934
Barry Warsaw53699e91996-12-10 23:23:01 +00003935 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003936 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003937 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003938 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003939 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003940 return NULL;
3941 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003942 Py_INCREF(Py_None);
3943 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003944}
3945#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003946
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003947#ifdef NeXT
3948#define HAVE_PUTENV
3949/* Steve Spicklemire got this putenv from NeXTAnswers */
3950static int
3951putenv(char *newval)
3952{
3953 extern char **environ;
3954
3955 static int firstTime = 1;
3956 char **ep;
3957 char *cp;
3958 int esiz;
3959 char *np;
3960
3961 if (!(np = strchr(newval, '=')))
3962 return 1;
3963 *np = '\0';
3964
3965 /* look it up */
3966 for (ep=environ ; *ep ; ep++)
3967 {
3968 /* this should always be true... */
3969 if (cp = strchr(*ep, '='))
3970 {
3971 *cp = '\0';
3972 if (!strcmp(*ep, newval))
3973 {
3974 /* got it! */
3975 *cp = '=';
3976 break;
3977 }
3978 *cp = '=';
3979 }
3980 else
3981 {
3982 *np = '=';
3983 return 1;
3984 }
3985 }
3986
3987 *np = '=';
3988 if (*ep)
3989 {
3990 /* the string was already there:
3991 just replace it with the new one */
3992 *ep = newval;
3993 return 0;
3994 }
3995
3996 /* expand environ by one */
3997 for (esiz=2, ep=environ ; *ep ; ep++)
3998 esiz++;
3999 if (firstTime)
4000 {
4001 char **epp;
4002 char **newenv;
4003 if (!(newenv = malloc(esiz * sizeof(char *))))
4004 return 1;
4005
4006 for (ep=environ, epp=newenv ; *ep ;)
4007 *epp++ = *ep++;
4008 *epp++ = newval;
4009 *epp = (char *) 0;
4010 environ = newenv;
4011 }
4012 else
4013 {
4014 if (!(environ = realloc(environ, esiz * sizeof(char *))))
4015 return 1;
4016 environ[esiz - 2] = newval;
4017 environ[esiz - 1] = (char *) 0;
4018 firstTime = 0;
4019 }
4020
4021 return 0;
4022}
Guido van Rossumc6ef2041997-08-21 02:30:45 +00004023#endif /* NeXT */
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004024
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004025
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004026#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004027static char posix_putenv__doc__[] =
4028"putenv(key, value) -> None\n\
4029Change or add an environment variable.";
4030
Fred Drake762e2061999-08-26 17:23:54 +00004031/* Save putenv() parameters as values here, so we can collect them when they
4032 * get re-set with another call for the same key. */
4033static PyObject *posix_putenv_garbage;
4034
Barry Warsaw53699e91996-12-10 23:23:01 +00004035static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004036posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004037{
4038 char *s1, *s2;
4039 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00004040 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00004041 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004042
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004043 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004044 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00004045
4046#if defined(PYOS_OS2)
4047 if (stricmp(s1, "BEGINLIBPATH") == 0) {
4048 APIRET rc;
4049
4050 if (strlen(s2) == 0) /* If New Value is an Empty String */
4051 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4052
4053 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
4054 if (rc != NO_ERROR)
4055 return os2_error(rc);
4056
4057 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
4058 APIRET rc;
4059
4060 if (strlen(s2) == 0) /* If New Value is an Empty String */
4061 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4062
4063 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
4064 if (rc != NO_ERROR)
4065 return os2_error(rc);
4066 } else {
4067#endif
4068
Fred Drake762e2061999-08-26 17:23:54 +00004069 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00004070 len = strlen(s1) + strlen(s2) + 2;
4071 /* len includes space for a trailing \0; the size arg to
4072 PyString_FromStringAndSize does not count that */
4073 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00004074 if (newstr == NULL)
4075 return PyErr_NoMemory();
4076 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00004077 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004078 if (putenv(new)) {
4079 posix_error();
4080 return NULL;
4081 }
Fred Drake762e2061999-08-26 17:23:54 +00004082 /* Install the first arg and newstr in posix_putenv_garbage;
4083 * this will cause previous value to be collected. This has to
4084 * happen after the real putenv() call because the old value
4085 * was still accessible until then. */
4086 if (PyDict_SetItem(posix_putenv_garbage,
4087 PyTuple_GET_ITEM(args, 0), newstr)) {
4088 /* really not much we can do; just leak */
4089 PyErr_Clear();
4090 }
4091 else {
4092 Py_DECREF(newstr);
4093 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00004094
4095#if defined(PYOS_OS2)
4096 }
4097#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004098 Py_INCREF(Py_None);
4099 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004100}
Guido van Rossumb6a47161997-09-15 22:54:34 +00004101#endif /* putenv */
4102
Guido van Rossumc524d952001-10-19 01:31:59 +00004103#ifdef HAVE_UNSETENV
4104static char posix_unsetenv__doc__[] =
4105"unsetenv(key) -> None\n\
4106Delete an environment variable.";
4107
4108static PyObject *
4109posix_unsetenv(PyObject *self, PyObject *args)
4110{
4111 char *s1;
4112
4113 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
4114 return NULL;
4115
4116 unsetenv(s1);
4117
4118 /* Remove the key from posix_putenv_garbage;
4119 * this will cause it to be collected. This has to
4120 * happen after the real unsetenv() call because the
4121 * old value was still accessible until then.
4122 */
4123 if (PyDict_DelItem(posix_putenv_garbage,
4124 PyTuple_GET_ITEM(args, 0))) {
4125 /* really not much we can do; just leak */
4126 PyErr_Clear();
4127 }
4128
4129 Py_INCREF(Py_None);
4130 return Py_None;
4131}
4132#endif /* unsetenv */
4133
Guido van Rossumb6a47161997-09-15 22:54:34 +00004134#ifdef HAVE_STRERROR
4135static char posix_strerror__doc__[] =
4136"strerror(code) -> string\n\
4137Translate an error code to a message string.";
4138
Guido van Rossumf68d8e52001-04-14 17:55:09 +00004139static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004140posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00004141{
4142 int code;
4143 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004144 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00004145 return NULL;
4146 message = strerror(code);
4147 if (message == NULL) {
4148 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00004149 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004150 return NULL;
4151 }
4152 return PyString_FromString(message);
4153}
4154#endif /* strerror */
4155
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004156
Guido van Rossumc9641791998-08-04 15:26:23 +00004157#ifdef HAVE_SYS_WAIT_H
4158
4159#ifdef WIFSTOPPED
4160static char posix_WIFSTOPPED__doc__[] =
4161"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004162Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004163
4164static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004165posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004166{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004167#ifdef UNION_WAIT
4168 union wait status;
4169#define status_i (status.w_status)
4170#else
4171 int status;
4172#define status_i status
4173#endif
4174 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004175
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004176 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004177 {
4178 return NULL;
4179 }
4180
4181 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004182#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004183}
4184#endif /* WIFSTOPPED */
4185
4186#ifdef WIFSIGNALED
4187static char posix_WIFSIGNALED__doc__[] =
4188"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00004189Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004190
4191static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004192posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004193{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004194#ifdef UNION_WAIT
4195 union wait status;
4196#define status_i (status.w_status)
4197#else
4198 int status;
4199#define status_i status
4200#endif
4201 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004202
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004203 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004204 {
4205 return NULL;
4206 }
4207
4208 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004209#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004210}
4211#endif /* WIFSIGNALED */
4212
4213#ifdef WIFEXITED
4214static char posix_WIFEXITED__doc__[] =
4215"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004216Return true if the process returning 'status' exited using the exit()\n\
4217system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004218
4219static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004220posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004221{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004222#ifdef UNION_WAIT
4223 union wait status;
4224#define status_i (status.w_status)
4225#else
4226 int status;
4227#define status_i status
4228#endif
4229 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004230
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004231 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004232 {
4233 return NULL;
4234 }
4235
4236 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004237#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004238}
4239#endif /* WIFEXITED */
4240
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004241#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00004242static char posix_WEXITSTATUS__doc__[] =
4243"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004244Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004245
4246static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004247posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004248{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004249#ifdef UNION_WAIT
4250 union wait status;
4251#define status_i (status.w_status)
4252#else
4253 int status;
4254#define status_i status
4255#endif
4256 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004257
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004258 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004259 {
4260 return NULL;
4261 }
4262
4263 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004264#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004265}
4266#endif /* WEXITSTATUS */
4267
4268#ifdef WTERMSIG
4269static char posix_WTERMSIG__doc__[] =
4270"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004271Return the signal that terminated the process that provided the 'status'\n\
4272value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004273
4274static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004275posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004276{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004277#ifdef UNION_WAIT
4278 union wait status;
4279#define status_i (status.w_status)
4280#else
4281 int status;
4282#define status_i status
4283#endif
4284 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004285
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004286 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004287 {
4288 return NULL;
4289 }
4290
4291 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004292#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004293}
4294#endif /* WTERMSIG */
4295
4296#ifdef WSTOPSIG
4297static char posix_WSTOPSIG__doc__[] =
4298"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004299Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004300
4301static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004302posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004303{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004304#ifdef UNION_WAIT
4305 union wait status;
4306#define status_i (status.w_status)
4307#else
4308 int status;
4309#define status_i status
4310#endif
4311 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004312
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004313 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004314 {
4315 return NULL;
4316 }
4317
4318 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004319#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004320}
4321#endif /* WSTOPSIG */
4322
4323#endif /* HAVE_SYS_WAIT_H */
4324
4325
Guido van Rossum94f6f721999-01-06 18:42:14 +00004326#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00004327#ifdef _SCO_DS
4328/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
4329 needed definitions in sys/statvfs.h */
4330#define _SVID3
4331#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004332#include <sys/statvfs.h>
4333
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004334static PyObject*
4335_pystatvfs_fromstructstatvfs(struct statvfs st) {
4336 PyObject *v = PyStructSequence_New(&StatVFSResultType);
4337 if (v == NULL)
4338 return NULL;
4339
4340#if !defined(HAVE_LARGEFILE_SUPPORT)
4341 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
4342 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
4343 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
4344 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
4345 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
4346 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
4347 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
4348 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
4349 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
4350 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
4351#else
4352 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
4353 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
4354 PyStructSequence_SET_ITEM(v, 2,
4355 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
4356 PyStructSequence_SET_ITEM(v, 3,
4357 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
4358 PyStructSequence_SET_ITEM(v, 4,
4359 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
4360 PyStructSequence_SET_ITEM(v, 5,
4361 PyLong_FromLongLong((LONG_LONG) st.f_files));
4362 PyStructSequence_SET_ITEM(v, 6,
4363 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
4364 PyStructSequence_SET_ITEM(v, 7,
4365 PyLong_FromLongLong((LONG_LONG) st.f_favail));
4366 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
4367 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
4368#endif
4369
4370 return v;
4371}
4372
Guido van Rossum94f6f721999-01-06 18:42:14 +00004373static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004374"fstatvfs(fd) -> \n\
4375 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004376Perform an fstatvfs system call on the given fd.";
4377
4378static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004379posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004380{
4381 int fd, res;
4382 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004383
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004384 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004385 return NULL;
4386 Py_BEGIN_ALLOW_THREADS
4387 res = fstatvfs(fd, &st);
4388 Py_END_ALLOW_THREADS
4389 if (res != 0)
4390 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004391
4392 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004393}
4394#endif /* HAVE_FSTATVFS */
4395
4396
4397#if defined(HAVE_STATVFS)
4398#include <sys/statvfs.h>
4399
4400static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004401"statvfs(path) -> \n\
4402 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004403Perform a statvfs system call on the given path.";
4404
4405static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004406posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004407{
4408 char *path;
4409 int res;
4410 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004411 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004412 return NULL;
4413 Py_BEGIN_ALLOW_THREADS
4414 res = statvfs(path, &st);
4415 Py_END_ALLOW_THREADS
4416 if (res != 0)
4417 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004418
4419 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004420}
4421#endif /* HAVE_STATVFS */
4422
4423
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004424#ifdef HAVE_TEMPNAM
4425static char posix_tempnam__doc__[] = "\
4426tempnam([dir[, prefix]]) -> string\n\
4427Return a unique name for a temporary file.\n\
4428The directory and a short may be specified as strings; they may be omitted\n\
4429or None if not needed.";
4430
4431static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004432posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004433{
4434 PyObject *result = NULL;
4435 char *dir = NULL;
4436 char *pfx = NULL;
4437 char *name;
4438
4439 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
4440 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00004441
4442 if (PyErr_Warn(PyExc_RuntimeWarning,
4443 "tempnam is a potential security risk to your program") < 0)
4444 return NULL;
4445
Fred Drake78b71c22001-07-17 20:37:36 +00004446#ifdef MS_WIN32
4447 name = _tempnam(dir, pfx);
4448#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004449 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00004450#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004451 if (name == NULL)
4452 return PyErr_NoMemory();
4453 result = PyString_FromString(name);
4454 free(name);
4455 return result;
4456}
Guido van Rossumd371ff11999-01-25 16:12:23 +00004457#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004458
4459
4460#ifdef HAVE_TMPFILE
4461static char posix_tmpfile__doc__[] = "\
4462tmpfile() -> file object\n\
4463Create a temporary file with no directory entries.";
4464
4465static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004466posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004467{
4468 FILE *fp;
4469
4470 if (!PyArg_ParseTuple(args, ":tmpfile"))
4471 return NULL;
4472 fp = tmpfile();
4473 if (fp == NULL)
4474 return posix_error();
4475 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
4476}
4477#endif
4478
4479
4480#ifdef HAVE_TMPNAM
4481static char posix_tmpnam__doc__[] = "\
4482tmpnam() -> string\n\
4483Return a unique name for a temporary file.";
4484
4485static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004486posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004487{
4488 char buffer[L_tmpnam];
4489 char *name;
4490
4491 if (!PyArg_ParseTuple(args, ":tmpnam"))
4492 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00004493
4494 if (PyErr_Warn(PyExc_RuntimeWarning,
4495 "tmpnam is a potential security risk to your program") < 0)
4496 return NULL;
4497
Greg Wardb48bc172000-03-01 21:51:56 +00004498#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004499 name = tmpnam_r(buffer);
4500#else
4501 name = tmpnam(buffer);
4502#endif
4503 if (name == NULL) {
4504 PyErr_SetObject(PyExc_OSError,
4505 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00004506#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004507 "unexpected NULL from tmpnam_r"
4508#else
4509 "unexpected NULL from tmpnam"
4510#endif
4511 ));
4512 return NULL;
4513 }
4514 return PyString_FromString(buffer);
4515}
4516#endif
4517
4518
Fred Drakec9680921999-12-13 16:37:25 +00004519/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
4520 * It maps strings representing configuration variable names to
4521 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00004522 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00004523 * rarely-used constants. There are three separate tables that use
4524 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00004525 *
4526 * This code is always included, even if none of the interfaces that
4527 * need it are included. The #if hackery needed to avoid it would be
4528 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00004529 */
4530struct constdef {
4531 char *name;
4532 long value;
4533};
4534
Fred Drake12c6e2d1999-12-14 21:25:03 +00004535static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004536conv_confname(PyObject *arg, int *valuep, struct constdef *table,
4537 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004538{
4539 if (PyInt_Check(arg)) {
4540 *valuep = PyInt_AS_LONG(arg);
4541 return 1;
4542 }
4543 if (PyString_Check(arg)) {
4544 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00004545 size_t lo = 0;
4546 size_t mid;
4547 size_t hi = tablesize;
4548 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004549 char *confname = PyString_AS_STRING(arg);
4550 while (lo < hi) {
4551 mid = (lo + hi) / 2;
4552 cmp = strcmp(confname, table[mid].name);
4553 if (cmp < 0)
4554 hi = mid;
4555 else if (cmp > 0)
4556 lo = mid + 1;
4557 else {
4558 *valuep = table[mid].value;
4559 return 1;
4560 }
4561 }
4562 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
4563 }
4564 else
4565 PyErr_SetString(PyExc_TypeError,
4566 "configuration names must be strings or integers");
4567 return 0;
4568}
4569
4570
4571#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4572static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004573#ifdef _PC_ABI_AIO_XFER_MAX
4574 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
4575#endif
4576#ifdef _PC_ABI_ASYNC_IO
4577 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
4578#endif
Fred Drakec9680921999-12-13 16:37:25 +00004579#ifdef _PC_ASYNC_IO
4580 {"PC_ASYNC_IO", _PC_ASYNC_IO},
4581#endif
4582#ifdef _PC_CHOWN_RESTRICTED
4583 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
4584#endif
4585#ifdef _PC_FILESIZEBITS
4586 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
4587#endif
4588#ifdef _PC_LAST
4589 {"PC_LAST", _PC_LAST},
4590#endif
4591#ifdef _PC_LINK_MAX
4592 {"PC_LINK_MAX", _PC_LINK_MAX},
4593#endif
4594#ifdef _PC_MAX_CANON
4595 {"PC_MAX_CANON", _PC_MAX_CANON},
4596#endif
4597#ifdef _PC_MAX_INPUT
4598 {"PC_MAX_INPUT", _PC_MAX_INPUT},
4599#endif
4600#ifdef _PC_NAME_MAX
4601 {"PC_NAME_MAX", _PC_NAME_MAX},
4602#endif
4603#ifdef _PC_NO_TRUNC
4604 {"PC_NO_TRUNC", _PC_NO_TRUNC},
4605#endif
4606#ifdef _PC_PATH_MAX
4607 {"PC_PATH_MAX", _PC_PATH_MAX},
4608#endif
4609#ifdef _PC_PIPE_BUF
4610 {"PC_PIPE_BUF", _PC_PIPE_BUF},
4611#endif
4612#ifdef _PC_PRIO_IO
4613 {"PC_PRIO_IO", _PC_PRIO_IO},
4614#endif
4615#ifdef _PC_SOCK_MAXBUF
4616 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
4617#endif
4618#ifdef _PC_SYNC_IO
4619 {"PC_SYNC_IO", _PC_SYNC_IO},
4620#endif
4621#ifdef _PC_VDISABLE
4622 {"PC_VDISABLE", _PC_VDISABLE},
4623#endif
4624};
4625
Fred Drakec9680921999-12-13 16:37:25 +00004626static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004627conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004628{
4629 return conv_confname(arg, valuep, posix_constants_pathconf,
4630 sizeof(posix_constants_pathconf)
4631 / sizeof(struct constdef));
4632}
4633#endif
4634
4635#ifdef HAVE_FPATHCONF
4636static char posix_fpathconf__doc__[] = "\
4637fpathconf(fd, name) -> integer\n\
4638Return the configuration limit name for the file descriptor fd.\n\
4639If there is no limit, return -1.";
4640
4641static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004642posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004643{
4644 PyObject *result = NULL;
4645 int name, fd;
4646
Fred Drake12c6e2d1999-12-14 21:25:03 +00004647 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4648 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00004649 long limit;
4650
4651 errno = 0;
4652 limit = fpathconf(fd, name);
4653 if (limit == -1 && errno != 0)
4654 posix_error();
4655 else
4656 result = PyInt_FromLong(limit);
4657 }
4658 return result;
4659}
4660#endif
4661
4662
4663#ifdef HAVE_PATHCONF
4664static char posix_pathconf__doc__[] = "\
4665pathconf(path, name) -> integer\n\
4666Return the configuration limit name for the file or directory path.\n\
4667If there is no limit, return -1.";
4668
4669static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004670posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004671{
4672 PyObject *result = NULL;
4673 int name;
4674 char *path;
4675
4676 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4677 conv_path_confname, &name)) {
4678 long limit;
4679
4680 errno = 0;
4681 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004682 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00004683 if (errno == EINVAL)
4684 /* could be a path or name problem */
4685 posix_error();
4686 else
4687 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004688 }
Fred Drakec9680921999-12-13 16:37:25 +00004689 else
4690 result = PyInt_FromLong(limit);
4691 }
4692 return result;
4693}
4694#endif
4695
4696#ifdef HAVE_CONFSTR
4697static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004698#ifdef _CS_ARCHITECTURE
4699 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4700#endif
4701#ifdef _CS_HOSTNAME
4702 {"CS_HOSTNAME", _CS_HOSTNAME},
4703#endif
4704#ifdef _CS_HW_PROVIDER
4705 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4706#endif
4707#ifdef _CS_HW_SERIAL
4708 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4709#endif
4710#ifdef _CS_INITTAB_NAME
4711 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4712#endif
Fred Drakec9680921999-12-13 16:37:25 +00004713#ifdef _CS_LFS64_CFLAGS
4714 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4715#endif
4716#ifdef _CS_LFS64_LDFLAGS
4717 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4718#endif
4719#ifdef _CS_LFS64_LIBS
4720 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4721#endif
4722#ifdef _CS_LFS64_LINTFLAGS
4723 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4724#endif
4725#ifdef _CS_LFS_CFLAGS
4726 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4727#endif
4728#ifdef _CS_LFS_LDFLAGS
4729 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4730#endif
4731#ifdef _CS_LFS_LIBS
4732 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4733#endif
4734#ifdef _CS_LFS_LINTFLAGS
4735 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4736#endif
Fred Draked86ed291999-12-15 15:34:33 +00004737#ifdef _CS_MACHINE
4738 {"CS_MACHINE", _CS_MACHINE},
4739#endif
Fred Drakec9680921999-12-13 16:37:25 +00004740#ifdef _CS_PATH
4741 {"CS_PATH", _CS_PATH},
4742#endif
Fred Draked86ed291999-12-15 15:34:33 +00004743#ifdef _CS_RELEASE
4744 {"CS_RELEASE", _CS_RELEASE},
4745#endif
4746#ifdef _CS_SRPC_DOMAIN
4747 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4748#endif
4749#ifdef _CS_SYSNAME
4750 {"CS_SYSNAME", _CS_SYSNAME},
4751#endif
4752#ifdef _CS_VERSION
4753 {"CS_VERSION", _CS_VERSION},
4754#endif
Fred Drakec9680921999-12-13 16:37:25 +00004755#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4756 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4757#endif
4758#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4759 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4760#endif
4761#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4762 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4763#endif
4764#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4765 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4766#endif
4767#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4768 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4769#endif
4770#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4771 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4772#endif
4773#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4774 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4775#endif
4776#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4777 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4778#endif
4779#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4780 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4781#endif
4782#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4783 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4784#endif
4785#ifdef _CS_XBS5_LP64_OFF64_LIBS
4786 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4787#endif
4788#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4789 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4790#endif
4791#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4792 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4793#endif
4794#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4795 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4796#endif
4797#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4798 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4799#endif
4800#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4801 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4802#endif
Fred Draked86ed291999-12-15 15:34:33 +00004803#ifdef _MIPS_CS_AVAIL_PROCESSORS
4804 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4805#endif
4806#ifdef _MIPS_CS_BASE
4807 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4808#endif
4809#ifdef _MIPS_CS_HOSTID
4810 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4811#endif
4812#ifdef _MIPS_CS_HW_NAME
4813 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4814#endif
4815#ifdef _MIPS_CS_NUM_PROCESSORS
4816 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4817#endif
4818#ifdef _MIPS_CS_OSREL_MAJ
4819 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4820#endif
4821#ifdef _MIPS_CS_OSREL_MIN
4822 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4823#endif
4824#ifdef _MIPS_CS_OSREL_PATCH
4825 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4826#endif
4827#ifdef _MIPS_CS_OS_NAME
4828 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4829#endif
4830#ifdef _MIPS_CS_OS_PROVIDER
4831 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4832#endif
4833#ifdef _MIPS_CS_PROCESSORS
4834 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4835#endif
4836#ifdef _MIPS_CS_SERIAL
4837 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4838#endif
4839#ifdef _MIPS_CS_VENDOR
4840 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4841#endif
Fred Drakec9680921999-12-13 16:37:25 +00004842};
4843
4844static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004845conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004846{
4847 return conv_confname(arg, valuep, posix_constants_confstr,
4848 sizeof(posix_constants_confstr)
4849 / sizeof(struct constdef));
4850}
4851
4852static char posix_confstr__doc__[] = "\
4853confstr(name) -> string\n\
4854Return a string-valued system configuration variable.";
4855
4856static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004857posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004858{
4859 PyObject *result = NULL;
4860 int name;
4861 char buffer[64];
4862
4863 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4864 int len = confstr(name, buffer, sizeof(buffer));
4865
Fred Drakec9680921999-12-13 16:37:25 +00004866 errno = 0;
4867 if (len == 0) {
4868 if (errno != 0)
4869 posix_error();
4870 else
4871 result = PyString_FromString("");
4872 }
4873 else {
4874 if (len >= sizeof(buffer)) {
4875 result = PyString_FromStringAndSize(NULL, len);
4876 if (result != NULL)
4877 confstr(name, PyString_AS_STRING(result), len+1);
4878 }
4879 else
4880 result = PyString_FromString(buffer);
4881 }
4882 }
4883 return result;
4884}
4885#endif
4886
4887
4888#ifdef HAVE_SYSCONF
4889static struct constdef posix_constants_sysconf[] = {
4890#ifdef _SC_2_CHAR_TERM
4891 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4892#endif
4893#ifdef _SC_2_C_BIND
4894 {"SC_2_C_BIND", _SC_2_C_BIND},
4895#endif
4896#ifdef _SC_2_C_DEV
4897 {"SC_2_C_DEV", _SC_2_C_DEV},
4898#endif
4899#ifdef _SC_2_C_VERSION
4900 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4901#endif
4902#ifdef _SC_2_FORT_DEV
4903 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4904#endif
4905#ifdef _SC_2_FORT_RUN
4906 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4907#endif
4908#ifdef _SC_2_LOCALEDEF
4909 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4910#endif
4911#ifdef _SC_2_SW_DEV
4912 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4913#endif
4914#ifdef _SC_2_UPE
4915 {"SC_2_UPE", _SC_2_UPE},
4916#endif
4917#ifdef _SC_2_VERSION
4918 {"SC_2_VERSION", _SC_2_VERSION},
4919#endif
Fred Draked86ed291999-12-15 15:34:33 +00004920#ifdef _SC_ABI_ASYNCHRONOUS_IO
4921 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4922#endif
4923#ifdef _SC_ACL
4924 {"SC_ACL", _SC_ACL},
4925#endif
Fred Drakec9680921999-12-13 16:37:25 +00004926#ifdef _SC_AIO_LISTIO_MAX
4927 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4928#endif
Fred Drakec9680921999-12-13 16:37:25 +00004929#ifdef _SC_AIO_MAX
4930 {"SC_AIO_MAX", _SC_AIO_MAX},
4931#endif
4932#ifdef _SC_AIO_PRIO_DELTA_MAX
4933 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4934#endif
4935#ifdef _SC_ARG_MAX
4936 {"SC_ARG_MAX", _SC_ARG_MAX},
4937#endif
4938#ifdef _SC_ASYNCHRONOUS_IO
4939 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4940#endif
4941#ifdef _SC_ATEXIT_MAX
4942 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4943#endif
Fred Draked86ed291999-12-15 15:34:33 +00004944#ifdef _SC_AUDIT
4945 {"SC_AUDIT", _SC_AUDIT},
4946#endif
Fred Drakec9680921999-12-13 16:37:25 +00004947#ifdef _SC_AVPHYS_PAGES
4948 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4949#endif
4950#ifdef _SC_BC_BASE_MAX
4951 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4952#endif
4953#ifdef _SC_BC_DIM_MAX
4954 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4955#endif
4956#ifdef _SC_BC_SCALE_MAX
4957 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4958#endif
4959#ifdef _SC_BC_STRING_MAX
4960 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4961#endif
Fred Draked86ed291999-12-15 15:34:33 +00004962#ifdef _SC_CAP
4963 {"SC_CAP", _SC_CAP},
4964#endif
Fred Drakec9680921999-12-13 16:37:25 +00004965#ifdef _SC_CHARCLASS_NAME_MAX
4966 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4967#endif
4968#ifdef _SC_CHAR_BIT
4969 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4970#endif
4971#ifdef _SC_CHAR_MAX
4972 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4973#endif
4974#ifdef _SC_CHAR_MIN
4975 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4976#endif
4977#ifdef _SC_CHILD_MAX
4978 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4979#endif
4980#ifdef _SC_CLK_TCK
4981 {"SC_CLK_TCK", _SC_CLK_TCK},
4982#endif
4983#ifdef _SC_COHER_BLKSZ
4984 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4985#endif
4986#ifdef _SC_COLL_WEIGHTS_MAX
4987 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4988#endif
4989#ifdef _SC_DCACHE_ASSOC
4990 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4991#endif
4992#ifdef _SC_DCACHE_BLKSZ
4993 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4994#endif
4995#ifdef _SC_DCACHE_LINESZ
4996 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4997#endif
4998#ifdef _SC_DCACHE_SZ
4999 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
5000#endif
5001#ifdef _SC_DCACHE_TBLKSZ
5002 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
5003#endif
5004#ifdef _SC_DELAYTIMER_MAX
5005 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
5006#endif
5007#ifdef _SC_EQUIV_CLASS_MAX
5008 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
5009#endif
5010#ifdef _SC_EXPR_NEST_MAX
5011 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
5012#endif
5013#ifdef _SC_FSYNC
5014 {"SC_FSYNC", _SC_FSYNC},
5015#endif
5016#ifdef _SC_GETGR_R_SIZE_MAX
5017 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
5018#endif
5019#ifdef _SC_GETPW_R_SIZE_MAX
5020 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
5021#endif
5022#ifdef _SC_ICACHE_ASSOC
5023 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
5024#endif
5025#ifdef _SC_ICACHE_BLKSZ
5026 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
5027#endif
5028#ifdef _SC_ICACHE_LINESZ
5029 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
5030#endif
5031#ifdef _SC_ICACHE_SZ
5032 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
5033#endif
Fred Draked86ed291999-12-15 15:34:33 +00005034#ifdef _SC_INF
5035 {"SC_INF", _SC_INF},
5036#endif
Fred Drakec9680921999-12-13 16:37:25 +00005037#ifdef _SC_INT_MAX
5038 {"SC_INT_MAX", _SC_INT_MAX},
5039#endif
5040#ifdef _SC_INT_MIN
5041 {"SC_INT_MIN", _SC_INT_MIN},
5042#endif
5043#ifdef _SC_IOV_MAX
5044 {"SC_IOV_MAX", _SC_IOV_MAX},
5045#endif
Fred Draked86ed291999-12-15 15:34:33 +00005046#ifdef _SC_IP_SECOPTS
5047 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
5048#endif
Fred Drakec9680921999-12-13 16:37:25 +00005049#ifdef _SC_JOB_CONTROL
5050 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
5051#endif
Fred Draked86ed291999-12-15 15:34:33 +00005052#ifdef _SC_KERN_POINTERS
5053 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
5054#endif
5055#ifdef _SC_KERN_SIM
5056 {"SC_KERN_SIM", _SC_KERN_SIM},
5057#endif
Fred Drakec9680921999-12-13 16:37:25 +00005058#ifdef _SC_LINE_MAX
5059 {"SC_LINE_MAX", _SC_LINE_MAX},
5060#endif
5061#ifdef _SC_LOGIN_NAME_MAX
5062 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
5063#endif
5064#ifdef _SC_LOGNAME_MAX
5065 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
5066#endif
5067#ifdef _SC_LONG_BIT
5068 {"SC_LONG_BIT", _SC_LONG_BIT},
5069#endif
Fred Draked86ed291999-12-15 15:34:33 +00005070#ifdef _SC_MAC
5071 {"SC_MAC", _SC_MAC},
5072#endif
Fred Drakec9680921999-12-13 16:37:25 +00005073#ifdef _SC_MAPPED_FILES
5074 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
5075#endif
5076#ifdef _SC_MAXPID
5077 {"SC_MAXPID", _SC_MAXPID},
5078#endif
5079#ifdef _SC_MB_LEN_MAX
5080 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
5081#endif
5082#ifdef _SC_MEMLOCK
5083 {"SC_MEMLOCK", _SC_MEMLOCK},
5084#endif
5085#ifdef _SC_MEMLOCK_RANGE
5086 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
5087#endif
5088#ifdef _SC_MEMORY_PROTECTION
5089 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
5090#endif
5091#ifdef _SC_MESSAGE_PASSING
5092 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
5093#endif
Fred Draked86ed291999-12-15 15:34:33 +00005094#ifdef _SC_MMAP_FIXED_ALIGNMENT
5095 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
5096#endif
Fred Drakec9680921999-12-13 16:37:25 +00005097#ifdef _SC_MQ_OPEN_MAX
5098 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
5099#endif
5100#ifdef _SC_MQ_PRIO_MAX
5101 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
5102#endif
Fred Draked86ed291999-12-15 15:34:33 +00005103#ifdef _SC_NACLS_MAX
5104 {"SC_NACLS_MAX", _SC_NACLS_MAX},
5105#endif
Fred Drakec9680921999-12-13 16:37:25 +00005106#ifdef _SC_NGROUPS_MAX
5107 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
5108#endif
5109#ifdef _SC_NL_ARGMAX
5110 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
5111#endif
5112#ifdef _SC_NL_LANGMAX
5113 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
5114#endif
5115#ifdef _SC_NL_MSGMAX
5116 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
5117#endif
5118#ifdef _SC_NL_NMAX
5119 {"SC_NL_NMAX", _SC_NL_NMAX},
5120#endif
5121#ifdef _SC_NL_SETMAX
5122 {"SC_NL_SETMAX", _SC_NL_SETMAX},
5123#endif
5124#ifdef _SC_NL_TEXTMAX
5125 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
5126#endif
5127#ifdef _SC_NPROCESSORS_CONF
5128 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
5129#endif
5130#ifdef _SC_NPROCESSORS_ONLN
5131 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
5132#endif
Fred Draked86ed291999-12-15 15:34:33 +00005133#ifdef _SC_NPROC_CONF
5134 {"SC_NPROC_CONF", _SC_NPROC_CONF},
5135#endif
5136#ifdef _SC_NPROC_ONLN
5137 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
5138#endif
Fred Drakec9680921999-12-13 16:37:25 +00005139#ifdef _SC_NZERO
5140 {"SC_NZERO", _SC_NZERO},
5141#endif
5142#ifdef _SC_OPEN_MAX
5143 {"SC_OPEN_MAX", _SC_OPEN_MAX},
5144#endif
5145#ifdef _SC_PAGESIZE
5146 {"SC_PAGESIZE", _SC_PAGESIZE},
5147#endif
5148#ifdef _SC_PAGE_SIZE
5149 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
5150#endif
5151#ifdef _SC_PASS_MAX
5152 {"SC_PASS_MAX", _SC_PASS_MAX},
5153#endif
5154#ifdef _SC_PHYS_PAGES
5155 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
5156#endif
5157#ifdef _SC_PII
5158 {"SC_PII", _SC_PII},
5159#endif
5160#ifdef _SC_PII_INTERNET
5161 {"SC_PII_INTERNET", _SC_PII_INTERNET},
5162#endif
5163#ifdef _SC_PII_INTERNET_DGRAM
5164 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
5165#endif
5166#ifdef _SC_PII_INTERNET_STREAM
5167 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
5168#endif
5169#ifdef _SC_PII_OSI
5170 {"SC_PII_OSI", _SC_PII_OSI},
5171#endif
5172#ifdef _SC_PII_OSI_CLTS
5173 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
5174#endif
5175#ifdef _SC_PII_OSI_COTS
5176 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
5177#endif
5178#ifdef _SC_PII_OSI_M
5179 {"SC_PII_OSI_M", _SC_PII_OSI_M},
5180#endif
5181#ifdef _SC_PII_SOCKET
5182 {"SC_PII_SOCKET", _SC_PII_SOCKET},
5183#endif
5184#ifdef _SC_PII_XTI
5185 {"SC_PII_XTI", _SC_PII_XTI},
5186#endif
5187#ifdef _SC_POLL
5188 {"SC_POLL", _SC_POLL},
5189#endif
5190#ifdef _SC_PRIORITIZED_IO
5191 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
5192#endif
5193#ifdef _SC_PRIORITY_SCHEDULING
5194 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
5195#endif
5196#ifdef _SC_REALTIME_SIGNALS
5197 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
5198#endif
5199#ifdef _SC_RE_DUP_MAX
5200 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
5201#endif
5202#ifdef _SC_RTSIG_MAX
5203 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
5204#endif
5205#ifdef _SC_SAVED_IDS
5206 {"SC_SAVED_IDS", _SC_SAVED_IDS},
5207#endif
5208#ifdef _SC_SCHAR_MAX
5209 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
5210#endif
5211#ifdef _SC_SCHAR_MIN
5212 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
5213#endif
5214#ifdef _SC_SELECT
5215 {"SC_SELECT", _SC_SELECT},
5216#endif
5217#ifdef _SC_SEMAPHORES
5218 {"SC_SEMAPHORES", _SC_SEMAPHORES},
5219#endif
5220#ifdef _SC_SEM_NSEMS_MAX
5221 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
5222#endif
5223#ifdef _SC_SEM_VALUE_MAX
5224 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
5225#endif
5226#ifdef _SC_SHARED_MEMORY_OBJECTS
5227 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
5228#endif
5229#ifdef _SC_SHRT_MAX
5230 {"SC_SHRT_MAX", _SC_SHRT_MAX},
5231#endif
5232#ifdef _SC_SHRT_MIN
5233 {"SC_SHRT_MIN", _SC_SHRT_MIN},
5234#endif
5235#ifdef _SC_SIGQUEUE_MAX
5236 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
5237#endif
5238#ifdef _SC_SIGRT_MAX
5239 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
5240#endif
5241#ifdef _SC_SIGRT_MIN
5242 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
5243#endif
Fred Draked86ed291999-12-15 15:34:33 +00005244#ifdef _SC_SOFTPOWER
5245 {"SC_SOFTPOWER", _SC_SOFTPOWER},
5246#endif
Fred Drakec9680921999-12-13 16:37:25 +00005247#ifdef _SC_SPLIT_CACHE
5248 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
5249#endif
5250#ifdef _SC_SSIZE_MAX
5251 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
5252#endif
5253#ifdef _SC_STACK_PROT
5254 {"SC_STACK_PROT", _SC_STACK_PROT},
5255#endif
5256#ifdef _SC_STREAM_MAX
5257 {"SC_STREAM_MAX", _SC_STREAM_MAX},
5258#endif
5259#ifdef _SC_SYNCHRONIZED_IO
5260 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
5261#endif
5262#ifdef _SC_THREADS
5263 {"SC_THREADS", _SC_THREADS},
5264#endif
5265#ifdef _SC_THREAD_ATTR_STACKADDR
5266 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
5267#endif
5268#ifdef _SC_THREAD_ATTR_STACKSIZE
5269 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
5270#endif
5271#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
5272 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
5273#endif
5274#ifdef _SC_THREAD_KEYS_MAX
5275 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
5276#endif
5277#ifdef _SC_THREAD_PRIORITY_SCHEDULING
5278 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
5279#endif
5280#ifdef _SC_THREAD_PRIO_INHERIT
5281 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
5282#endif
5283#ifdef _SC_THREAD_PRIO_PROTECT
5284 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
5285#endif
5286#ifdef _SC_THREAD_PROCESS_SHARED
5287 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
5288#endif
5289#ifdef _SC_THREAD_SAFE_FUNCTIONS
5290 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
5291#endif
5292#ifdef _SC_THREAD_STACK_MIN
5293 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
5294#endif
5295#ifdef _SC_THREAD_THREADS_MAX
5296 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
5297#endif
5298#ifdef _SC_TIMERS
5299 {"SC_TIMERS", _SC_TIMERS},
5300#endif
5301#ifdef _SC_TIMER_MAX
5302 {"SC_TIMER_MAX", _SC_TIMER_MAX},
5303#endif
5304#ifdef _SC_TTY_NAME_MAX
5305 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
5306#endif
5307#ifdef _SC_TZNAME_MAX
5308 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
5309#endif
5310#ifdef _SC_T_IOV_MAX
5311 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
5312#endif
5313#ifdef _SC_UCHAR_MAX
5314 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
5315#endif
5316#ifdef _SC_UINT_MAX
5317 {"SC_UINT_MAX", _SC_UINT_MAX},
5318#endif
5319#ifdef _SC_UIO_MAXIOV
5320 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
5321#endif
5322#ifdef _SC_ULONG_MAX
5323 {"SC_ULONG_MAX", _SC_ULONG_MAX},
5324#endif
5325#ifdef _SC_USHRT_MAX
5326 {"SC_USHRT_MAX", _SC_USHRT_MAX},
5327#endif
5328#ifdef _SC_VERSION
5329 {"SC_VERSION", _SC_VERSION},
5330#endif
5331#ifdef _SC_WORD_BIT
5332 {"SC_WORD_BIT", _SC_WORD_BIT},
5333#endif
5334#ifdef _SC_XBS5_ILP32_OFF32
5335 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
5336#endif
5337#ifdef _SC_XBS5_ILP32_OFFBIG
5338 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
5339#endif
5340#ifdef _SC_XBS5_LP64_OFF64
5341 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
5342#endif
5343#ifdef _SC_XBS5_LPBIG_OFFBIG
5344 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
5345#endif
5346#ifdef _SC_XOPEN_CRYPT
5347 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
5348#endif
5349#ifdef _SC_XOPEN_ENH_I18N
5350 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
5351#endif
5352#ifdef _SC_XOPEN_LEGACY
5353 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
5354#endif
5355#ifdef _SC_XOPEN_REALTIME
5356 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
5357#endif
5358#ifdef _SC_XOPEN_REALTIME_THREADS
5359 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
5360#endif
5361#ifdef _SC_XOPEN_SHM
5362 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
5363#endif
5364#ifdef _SC_XOPEN_UNIX
5365 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
5366#endif
5367#ifdef _SC_XOPEN_VERSION
5368 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
5369#endif
5370#ifdef _SC_XOPEN_XCU_VERSION
5371 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
5372#endif
5373#ifdef _SC_XOPEN_XPG2
5374 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
5375#endif
5376#ifdef _SC_XOPEN_XPG3
5377 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
5378#endif
5379#ifdef _SC_XOPEN_XPG4
5380 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
5381#endif
5382};
5383
5384static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005385conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005386{
5387 return conv_confname(arg, valuep, posix_constants_sysconf,
5388 sizeof(posix_constants_sysconf)
5389 / sizeof(struct constdef));
5390}
5391
5392static char posix_sysconf__doc__[] = "\
5393sysconf(name) -> integer\n\
5394Return an integer-valued system configuration variable.";
5395
5396static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005397posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005398{
5399 PyObject *result = NULL;
5400 int name;
5401
5402 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
5403 int value;
5404
5405 errno = 0;
5406 value = sysconf(name);
5407 if (value == -1 && errno != 0)
5408 posix_error();
5409 else
5410 result = PyInt_FromLong(value);
5411 }
5412 return result;
5413}
5414#endif
5415
5416
Fred Drakebec628d1999-12-15 18:31:10 +00005417/* This code is used to ensure that the tables of configuration value names
5418 * are in sorted order as required by conv_confname(), and also to build the
5419 * the exported dictionaries that are used to publish information about the
5420 * names available on the host platform.
5421 *
5422 * Sorting the table at runtime ensures that the table is properly ordered
5423 * when used, even for platforms we're not able to test on. It also makes
5424 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00005425 */
Fred Drakebec628d1999-12-15 18:31:10 +00005426
5427static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005428cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00005429{
5430 const struct constdef *c1 =
5431 (const struct constdef *) v1;
5432 const struct constdef *c2 =
5433 (const struct constdef *) v2;
5434
5435 return strcmp(c1->name, c2->name);
5436}
5437
5438static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005439setup_confname_table(struct constdef *table, size_t tablesize,
5440 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005441{
Fred Drakebec628d1999-12-15 18:31:10 +00005442 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00005443 size_t i;
5444 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00005445
5446 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
5447 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00005448 if (d == NULL)
5449 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005450
Barry Warsaw3155db32000-04-13 15:20:40 +00005451 for (i=0; i < tablesize; ++i) {
5452 PyObject *o = PyInt_FromLong(table[i].value);
5453 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
5454 Py_XDECREF(o);
5455 Py_DECREF(d);
5456 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005457 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005458 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00005459 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005460 status = PyDict_SetItemString(moddict, tablename, d);
5461 Py_DECREF(d);
5462 return status;
Fred Draked86ed291999-12-15 15:34:33 +00005463}
5464
Fred Drakebec628d1999-12-15 18:31:10 +00005465/* Return -1 on failure, 0 on success. */
5466static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005467setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005468{
5469#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00005470 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00005471 sizeof(posix_constants_pathconf)
5472 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005473 "pathconf_names", moddict))
5474 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005475#endif
5476#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00005477 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00005478 sizeof(posix_constants_confstr)
5479 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005480 "confstr_names", moddict))
5481 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005482#endif
5483#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00005484 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00005485 sizeof(posix_constants_sysconf)
5486 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005487 "sysconf_names", moddict))
5488 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005489#endif
Fred Drakebec628d1999-12-15 18:31:10 +00005490 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00005491}
Fred Draked86ed291999-12-15 15:34:33 +00005492
5493
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005494static char posix_abort__doc__[] = "\
5495abort() -> does not return!\n\
5496Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
5497in the hardest way possible on the hosting operating system.";
5498
5499static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005500posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005501{
5502 if (!PyArg_ParseTuple(args, ":abort"))
5503 return NULL;
5504 abort();
5505 /*NOTREACHED*/
5506 Py_FatalError("abort() called from Python code didn't abort!");
5507 return NULL;
5508}
Fred Drakebec628d1999-12-15 18:31:10 +00005509
Tim Petersf58a7aa2000-09-22 10:05:54 +00005510#ifdef MS_WIN32
5511static char win32_startfile__doc__[] = "\
5512startfile(filepath) - Start a file with its associated application.\n\
5513\n\
5514This acts like double-clicking the file in Explorer, or giving the file\n\
5515name as an argument to the DOS \"start\" command: the file is opened\n\
5516with whatever application (if any) its extension is associated.\n\
5517\n\
5518startfile returns as soon as the associated application is launched.\n\
5519There is no option to wait for the application to close, and no way\n\
5520to retrieve the application's exit status.\n\
5521\n\
5522The filepath is relative to the current directory. If you want to use\n\
5523an absolute path, make sure the first character is not a slash (\"/\");\n\
5524the underlying Win32 ShellExecute function doesn't work if it is.";
5525
5526static PyObject *
5527win32_startfile(PyObject *self, PyObject *args)
5528{
5529 char *filepath;
5530 HINSTANCE rc;
5531 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
5532 return NULL;
5533 Py_BEGIN_ALLOW_THREADS
5534 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
5535 Py_END_ALLOW_THREADS
5536 if (rc <= (HINSTANCE)32)
5537 return win32_error("startfile", filepath);
5538 Py_INCREF(Py_None);
5539 return Py_None;
5540}
5541#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005542
5543static PyMethodDef posix_methods[] = {
5544 {"access", posix_access, METH_VARARGS, posix_access__doc__},
5545#ifdef HAVE_TTYNAME
5546 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
5547#endif
5548 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
5549 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005550#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005551 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005552#endif /* HAVE_CHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00005553#ifdef HAVE_CHROOT
5554 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
5555#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005556#ifdef HAVE_CTERMID
5557 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
5558#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00005559#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005560 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00005561#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005562#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005563 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005564#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005565 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
5566 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
5567 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005568#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005569 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005570#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005571#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005572 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005573#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005574 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
5575 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
5576 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005577#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005578 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005579#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005580#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005581 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005582#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005583 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005584#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005585 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005586#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005587 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
5588 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
5589 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005590#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005591 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005592#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005593 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005594#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005595 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5596 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005597#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00005598#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005599 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5600 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00005601#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005602#ifdef HAVE_FORK1
5603 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
5604#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005605#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005606 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005607#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005608#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005609 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00005610#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005611#ifdef HAVE_FORKPTY
5612 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5613#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005614#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005615 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005616#endif /* HAVE_GETEGID */
5617#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005618 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005619#endif /* HAVE_GETEUID */
5620#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005621 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005622#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00005623#ifdef HAVE_GETGROUPS
5624 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5625#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005626 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005627#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005628 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005629#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005630#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005631 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005632#endif /* HAVE_GETPPID */
5633#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005634 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005635#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005636#ifdef HAVE_GETLOGIN
5637 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5638#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00005639#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005640 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005641#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00005642#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005643 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00005644#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005645#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005646 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005647#ifdef MS_WIN32
5648 {"popen2", win32_popen2, METH_VARARGS},
5649 {"popen3", win32_popen3, METH_VARARGS},
5650 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00005651 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005652#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005653#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005654#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005655 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005656#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005657#ifdef HAVE_SETEUID
5658 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5659#endif /* HAVE_SETEUID */
5660#ifdef HAVE_SETEGID
5661 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5662#endif /* HAVE_SETEGID */
5663#ifdef HAVE_SETREUID
5664 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5665#endif /* HAVE_SETREUID */
5666#ifdef HAVE_SETREGID
5667 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5668#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005669#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005670 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005671#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005672#ifdef HAVE_SETGROUPS
5673 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
5674#endif /* HAVE_SETGROUPS */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005675#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005676 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005677#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005678#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005679 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005680#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005681#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005682 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005683#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005684#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005685 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005686#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005687#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005688 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005689#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005690#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005691 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005692#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005693#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005694 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005695#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005696 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5697 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5698 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5699 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5700 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5701 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5702 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5703 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5704 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00005705 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005706#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005707 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005708#endif
5709#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005710 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005711#endif
5712#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005713 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005714#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005715#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005716 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005717#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00005718#ifdef HAVE_UNSETENV
5719 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
5720#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00005721#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005722 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00005723#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00005724#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005725 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005726#endif
5727#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005728 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005729#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00005730#ifdef HAVE_SYS_WAIT_H
5731#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005732 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005733#endif /* WIFSTOPPED */
5734#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005735 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005736#endif /* WIFSIGNALED */
5737#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005738 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005739#endif /* WIFEXITED */
5740#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005741 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005742#endif /* WEXITSTATUS */
5743#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005744 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005745#endif /* WTERMSIG */
5746#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005747 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005748#endif /* WSTOPSIG */
5749#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005750#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005751 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005752#endif
5753#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005754 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005755#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00005756#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005757 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5758#endif
5759#ifdef HAVE_TEMPNAM
5760 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5761#endif
5762#ifdef HAVE_TMPNAM
5763 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5764#endif
Fred Drakec9680921999-12-13 16:37:25 +00005765#ifdef HAVE_CONFSTR
5766 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5767#endif
5768#ifdef HAVE_SYSCONF
5769 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5770#endif
5771#ifdef HAVE_FPATHCONF
5772 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5773#endif
5774#ifdef HAVE_PATHCONF
5775 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5776#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005777 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00005778#ifdef MS_WIN32
5779 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
5780#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005781 {NULL, NULL} /* Sentinel */
5782};
5783
5784
Barry Warsaw4a342091996-12-19 23:50:02 +00005785static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005786ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005787{
5788 PyObject* v = PyInt_FromLong(value);
5789 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5790 return -1; /* triggers fatal error */
5791
5792 Py_DECREF(v);
5793 return 0;
5794}
5795
Guido van Rossumd48f2521997-12-05 22:19:34 +00005796#if defined(PYOS_OS2)
5797/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5798static int insertvalues(PyObject *d)
5799{
5800 APIRET rc;
5801 ULONG values[QSV_MAX+1];
5802 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00005803 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00005804
5805 Py_BEGIN_ALLOW_THREADS
5806 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5807 Py_END_ALLOW_THREADS
5808
5809 if (rc != NO_ERROR) {
5810 os2_error(rc);
5811 return -1;
5812 }
5813
5814 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5815 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5816 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5817 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5818 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5819 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5820 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5821
5822 switch (values[QSV_VERSION_MINOR]) {
5823 case 0: ver = "2.00"; break;
5824 case 10: ver = "2.10"; break;
5825 case 11: ver = "2.11"; break;
5826 case 30: ver = "3.00"; break;
5827 case 40: ver = "4.00"; break;
5828 case 50: ver = "5.00"; break;
5829 default:
Tim Peters885d4572001-11-28 20:27:42 +00005830 PyOS_snprintf(tmp, sizeof(tmp),
5831 "%d-%d", values[QSV_VERSION_MAJOR],
5832 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00005833 ver = &tmp[0];
5834 }
5835
5836 /* Add Indicator of the Version of the Operating System */
5837 v = PyString_FromString(ver);
5838 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5839 return -1;
5840 Py_DECREF(v);
5841
5842 /* Add Indicator of Which Drive was Used to Boot the System */
5843 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5844 tmp[1] = ':';
5845 tmp[2] = '\0';
5846
5847 v = PyString_FromString(tmp);
5848 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5849 return -1;
5850 Py_DECREF(v);
5851
5852 return 0;
5853}
5854#endif
5855
Barry Warsaw4a342091996-12-19 23:50:02 +00005856static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005857all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00005858{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005859#ifdef F_OK
5860 if (ins(d, "F_OK", (long)F_OK)) return -1;
5861#endif
5862#ifdef R_OK
5863 if (ins(d, "R_OK", (long)R_OK)) return -1;
5864#endif
5865#ifdef W_OK
5866 if (ins(d, "W_OK", (long)W_OK)) return -1;
5867#endif
5868#ifdef X_OK
5869 if (ins(d, "X_OK", (long)X_OK)) return -1;
5870#endif
Fred Drakec9680921999-12-13 16:37:25 +00005871#ifdef NGROUPS_MAX
5872 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5873#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005874#ifdef TMP_MAX
5875 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5876#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005877#ifdef WNOHANG
5878 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5879#endif
5880#ifdef O_RDONLY
5881 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5882#endif
5883#ifdef O_WRONLY
5884 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5885#endif
5886#ifdef O_RDWR
5887 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5888#endif
5889#ifdef O_NDELAY
5890 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5891#endif
5892#ifdef O_NONBLOCK
5893 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5894#endif
5895#ifdef O_APPEND
5896 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5897#endif
5898#ifdef O_DSYNC
5899 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5900#endif
5901#ifdef O_RSYNC
5902 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5903#endif
5904#ifdef O_SYNC
5905 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5906#endif
5907#ifdef O_NOCTTY
5908 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5909#endif
5910#ifdef O_CREAT
5911 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5912#endif
5913#ifdef O_EXCL
5914 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5915#endif
5916#ifdef O_TRUNC
5917 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5918#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005919#ifdef O_BINARY
5920 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5921#endif
5922#ifdef O_TEXT
5923 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5924#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00005925#ifdef O_LARGEFILE
5926 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
5927#endif
5928
5929/* GNU extensions. */
5930#ifdef O_DIRECT
5931 /* Direct disk access. */
5932 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
5933#endif
5934#ifdef O_DIRECTORY
5935 /* Must be a directory. */
5936 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
5937#endif
5938#ifdef O_NOFOLLOW
5939 /* Do not follow links. */
5940 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
5941#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005942
Guido van Rossum246bc171999-02-01 23:54:31 +00005943#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005944 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5945 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5946 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5947 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5948 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005949#endif
5950
Guido van Rossumd48f2521997-12-05 22:19:34 +00005951#if defined(PYOS_OS2)
5952 if (insertvalues(d)) return -1;
5953#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005954 return 0;
5955}
5956
5957
Tim Peters58e0a8c2001-05-14 22:32:33 +00005958#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005959#define INITFUNC initnt
5960#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00005961
5962#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005963#define INITFUNC initos2
5964#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00005965
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005966#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005967#define INITFUNC initposix
5968#define MODNAME "posix"
5969#endif
5970
Guido van Rossum3886bb61998-12-04 18:50:17 +00005971DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005972INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00005973{
Barry Warsaw53699e91996-12-10 23:23:01 +00005974 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005975
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005976 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005977 posix_methods,
5978 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005979 (PyObject *)NULL,
5980 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005981 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005982
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005983 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005984 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005985 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005986 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005987 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005988
Barry Warsaw4a342091996-12-19 23:50:02 +00005989 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005990 return;
5991
Fred Drakebec628d1999-12-15 18:31:10 +00005992 if (setup_confname_tables(d))
5993 return;
5994
Barry Warsawca74da41999-02-09 19:31:45 +00005995 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005996
Guido van Rossumb3d39562000-01-31 18:41:26 +00005997#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00005998 if (posix_putenv_garbage == NULL)
5999 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00006000#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006001
Guido van Rossum14648392001-12-08 18:02:58 +00006002 stat_result_desc.name = MODNAME ".stat_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006003 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
6004 PyDict_SetItemString(d, "stat_result", (PyObject*) &StatResultType);
6005
Guido van Rossum14648392001-12-08 18:02:58 +00006006 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006007 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Guido van Rossumbb2501f2001-12-27 16:23:28 +00006008 PyDict_SetItemString(d, "statvfs_result", (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006009}