blob: c342dcffb720f1a7c7041f64beca7eb6236f9553 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009******************************************************************/
10
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011/* POSIX module implementation */
12
Guido van Rossuma4916fa1996-05-23 22:58:55 +000013/* This file is also used for Windows NT and MS-Win. In that case the module
Guido van Rossumad0ee831995-03-01 10:34:45 +000014 actually calls itself 'nt', not 'posix', and a few functions are
15 either unimplemented or implemented differently. The source
Guido van Rossum8d665e61996-06-26 18:22:49 +000016 assumes that for Windows NT, the macro 'MS_WIN32' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +000017 of the compiler used. Different compilers define their own feature
Guido van Rossuma4916fa1996-05-23 22:58:55 +000018 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000019
Guido van Rossuma4916fa1996-05-23 22:58:55 +000020/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000021
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000022static char posix__doc__ [] =
23"This module provides access to operating system functionality that is\n\
24standardized by the C Standard and the POSIX standard (a thinly\n\
25disguised Unix interface). Refer to the library manual and\n\
26corresponding Unix manual entries for more information on calls.";
27
Barry Warsaw53699e91996-12-10 23:23:01 +000028#include "Python.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000029
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000030#if defined(PYOS_OS2)
31#define INCL_DOS
32#define INCL_DOSERRORS
33#define INCL_DOSPROCESS
34#define INCL_NOPMAPI
35#include <os2.h>
36#endif
37
Guido van Rossumb6775db1994-08-01 11:34:53 +000038#include <sys/types.h>
39#include <sys/stat.h>
Guido van Rossum36bc6801995-06-14 22:54:23 +000040#ifdef HAVE_SYS_WAIT_H
41#include <sys/wait.h> /* For WNOHANG */
42#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000043
Guido van Rossuma376cc51996-12-05 23:43:35 +000044#ifdef HAVE_SIGNAL_H
45#include <signal.h>
46#endif
47
Guido van Rossumb6775db1994-08-01 11:34:53 +000048#include "mytime.h" /* For clock_t on some systems */
49
50#ifdef HAVE_FCNTL_H
51#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000052#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000053
Guido van Rossuma4916fa1996-05-23 22:58:55 +000054/* Various compilers have only certain posix functions */
Guido van Rossum6d8841c1997-08-14 19:57:39 +000055/* XXX Gosh I wish these were all moved into config.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000056#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000057#include <process.h>
58#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000059#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000060#define HAVE_GETCWD 1
61#define HAVE_OPENDIR 1
62#define HAVE_SYSTEM 1
63#if defined(__OS2__)
64#define HAVE_EXECV 1
65#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000066#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000067#include <process.h>
68#else
69#ifdef __BORLANDC__ /* Borland compiler */
70#define HAVE_EXECV 1
71#define HAVE_GETCWD 1
72#define HAVE_GETEGID 1
73#define HAVE_GETEUID 1
74#define HAVE_GETGID 1
75#define HAVE_GETPPID 1
76#define HAVE_GETUID 1
77#define HAVE_KILL 1
78#define HAVE_OPENDIR 1
79#define HAVE_PIPE 1
80#define HAVE_POPEN 1
81#define HAVE_SYSTEM 1
82#define HAVE_WAIT 1
83#else
84#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000085#define HAVE_GETCWD 1
86#ifdef MS_WIN32
Guido van Rossuma1065681999-01-25 23:20:23 +000087#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000088#define HAVE_EXECV 1
89#define HAVE_PIPE 1
90#define HAVE_POPEN 1
91#define HAVE_SYSTEM 1
92#else /* 16-bit Windows */
Guido van Rossum8d665e61996-06-26 18:22:49 +000093#endif /* !MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000094#else /* all other compilers */
95/* Unix functions that the configure script doesn't check for */
96#define HAVE_EXECV 1
97#define HAVE_FORK 1
98#define HAVE_GETCWD 1
99#define HAVE_GETEGID 1
100#define HAVE_GETEUID 1
101#define HAVE_GETGID 1
102#define HAVE_GETPPID 1
103#define HAVE_GETUID 1
104#define HAVE_KILL 1
105#define HAVE_OPENDIR 1
106#define HAVE_PIPE 1
107#define HAVE_POPEN 1
108#define HAVE_SYSTEM 1
109#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000110#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000111#endif /* _MSC_VER */
112#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000113#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000114#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000115
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000116#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000117
Guido van Rossumb6775db1994-08-01 11:34:53 +0000118#ifdef HAVE_UNISTD_H
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000119#include <unistd.h>
Guido van Rossum36bc6801995-06-14 22:54:23 +0000120#endif
121
122#ifdef NeXT
123/* NeXT's <unistd.h> and <utime.h> aren't worth much */
124#undef HAVE_UNISTD_H
125#undef HAVE_UTIME_H
Guido van Rossumb9f866c1997-05-22 15:12:39 +0000126#define HAVE_WAITPID
Guido van Rossum36bc6801995-06-14 22:54:23 +0000127/* #undef HAVE_GETCWD */
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000128#define UNION_WAIT /* This should really be checked for by autoconf */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000129#endif
130
131#ifdef HAVE_UNISTD_H
Guido van Rossumad0ee831995-03-01 10:34:45 +0000132/* XXX These are for SunOS4.1.3 but shouldn't hurt elsewhere */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +0000133extern int rename(const char *, const char *);
134extern int pclose(FILE *);
135extern int lstat(const char *, struct stat *);
136extern int symlink(const char *, const char *);
137extern int fsync(int fd);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000138#else /* !HAVE_UNISTD_H */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000139#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000140extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000141#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000142#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000143extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000144#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000145extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000146#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000147#endif
148#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000149extern int chdir(char *);
150extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000151#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000152extern int chdir(const char *);
153extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000154#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000155extern int chmod(const char *, mode_t);
156extern int chown(const char *, uid_t, gid_t);
157extern char *getcwd(char *, int);
158extern char *strerror(int);
159extern int link(const char *, const char *);
160extern int rename(const char *, const char *);
161extern int stat(const char *, struct stat *);
162extern int unlink(const char *);
163extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000164#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000165extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000166#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000167#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000168extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000169#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000170#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000171
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000172#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000173
Guido van Rossumb6775db1994-08-01 11:34:53 +0000174#ifdef HAVE_UTIME_H
175#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000176#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000177
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000178#ifdef HAVE_SYS_UTIME_H
179#include <sys/utime.h>
180#define HAVE_UTIME_H /* pretend we do for the rest of this file */
181#endif /* HAVE_SYS_UTIME_H */
182
Guido van Rossumb6775db1994-08-01 11:34:53 +0000183#ifdef HAVE_SYS_TIMES_H
184#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000185#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000186
187#ifdef HAVE_SYS_PARAM_H
188#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000189#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000190
191#ifdef HAVE_SYS_UTSNAME_H
192#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000193#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000194
195#ifndef MAXPATHLEN
196#define MAXPATHLEN 1024
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000197#endif /* MAXPATHLEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000198
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000199#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000200#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000201#define NAMLEN(dirent) strlen((dirent)->d_name)
202#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000203#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000204#include <direct.h>
205#define NAMLEN(dirent) strlen((dirent)->d_name)
206#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000207#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000208#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000209#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000210#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000212#endif
213#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000215#endif
216#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000218#endif
219#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000220
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000221#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000222#include <direct.h>
223#include <io.h>
224#include <process.h>
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000225#define WINDOWS_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226#include <windows.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000227#ifdef MS_WIN32
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000228#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000229#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000230#else /* 16-bit Windows */
231#include <dos.h>
232#include <ctype.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000233#endif /* MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000234#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235
Guido van Rossumd48f2521997-12-05 22:19:34 +0000236#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000237#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000238#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000239
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000240#ifdef UNION_WAIT
241/* Emulate some macros on systems that have a union instead of macros */
242
243#ifndef WIFEXITED
244#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
245#endif
246
247#ifndef WEXITSTATUS
248#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
249#endif
250
251#ifndef WTERMSIG
252#define WTERMSIG(u_wait) ((u_wait).w_termsig)
253#endif
254
255#endif /* UNION_WAIT */
256
Greg Wardb48bc172000-03-01 21:51:56 +0000257/* Don't use the "_r" form if we don't need it (also, won't have a
258 prototype for it, at least on Solaris -- maybe others as well?). */
259#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
260#define USE_CTERMID_R
261#endif
262
263#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
264#define USE_TMPNAM_R
265#endif
266
Fred Drake699f3522000-06-29 21:12:41 +0000267/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000268#undef STAT
Fred Drake699f3522000-06-29 21:12:41 +0000269#ifdef MS_WIN64
270# define STAT _stati64
271# define FSTAT _fstati64
272# define STRUCT_STAT struct _stati64
273#else
274# define STAT stat
275# define FSTAT fstat
276# define STRUCT_STAT struct stat
277#endif
278
279
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000280/* Return a dictionary corresponding to the POSIX environment table */
281
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000282#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000283extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000284#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000285
Barry Warsaw53699e91996-12-10 23:23:01 +0000286static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000287convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000288{
Barry Warsaw53699e91996-12-10 23:23:01 +0000289 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000290 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000291 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000292 if (d == NULL)
293 return NULL;
294 if (environ == NULL)
295 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000296 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000297 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000298 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000299 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000300 char *p = strchr(*e, '=');
301 if (p == NULL)
302 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000303 k = PyString_FromStringAndSize(*e, (int)(p-*e));
304 if (k == NULL) {
305 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000306 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000307 }
308 v = PyString_FromString(p+1);
309 if (v == NULL) {
310 PyErr_Clear();
311 Py_DECREF(k);
312 continue;
313 }
314 if (PyDict_GetItem(d, k) == NULL) {
315 if (PyDict_SetItem(d, k, v) != 0)
316 PyErr_Clear();
317 }
318 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000319 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000320 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000321#if defined(PYOS_OS2)
322 {
323 APIRET rc;
324 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
325
326 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000327 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000328 PyObject *v = PyString_FromString(buffer);
329 PyDict_SetItemString(d, "BEGINLIBPATH", v);
330 Py_DECREF(v);
331 }
332 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
333 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
334 PyObject *v = PyString_FromString(buffer);
335 PyDict_SetItemString(d, "ENDLIBPATH", v);
336 Py_DECREF(v);
337 }
338 }
339#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000340 return d;
341}
342
343
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000344/* Set a POSIX-specific error from errno, and return NULL */
345
Barry Warsawd58d7641998-07-23 16:14:40 +0000346static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000347posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000348{
Barry Warsawca74da41999-02-09 19:31:45 +0000349 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000350}
Barry Warsawd58d7641998-07-23 16:14:40 +0000351static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000352posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000353{
Barry Warsawca74da41999-02-09 19:31:45 +0000354 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000355}
356
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000357#ifdef MS_WIN32
358static PyObject *
359win32_error(char* function, char* filename)
360{
361 /* XXX this could be improved */
362 errno = GetLastError();
363 if (filename)
364 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename);
365 else
366 return PyErr_SetFromErrno(PyExc_OSError);
367}
368#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000369
Guido van Rossumd48f2521997-12-05 22:19:34 +0000370#if defined(PYOS_OS2)
371/**********************************************************************
372 * Helper Function to Trim and Format OS/2 Messages
373 **********************************************************************/
374 static void
375os2_formatmsg(char *msgbuf, int msglen, char *reason)
376{
377 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
378
379 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
380 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
381
382 while (lastc > msgbuf && isspace(*lastc))
383 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
384 }
385
386 /* Add Optional Reason Text */
387 if (reason) {
388 strcat(msgbuf, " : ");
389 strcat(msgbuf, reason);
390 }
391}
392
393/**********************************************************************
394 * Decode an OS/2 Operating System Error Code
395 *
396 * A convenience function to lookup an OS/2 error code and return a
397 * text message we can use to raise a Python exception.
398 *
399 * Notes:
400 * The messages for errors returned from the OS/2 kernel reside in
401 * the file OSO001.MSG in the \OS2 directory hierarchy.
402 *
403 **********************************************************************/
404 static char *
405os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
406{
407 APIRET rc;
408 ULONG msglen;
409
410 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
411 Py_BEGIN_ALLOW_THREADS
412 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
413 errorcode, "oso001.msg", &msglen);
414 Py_END_ALLOW_THREADS
415
416 if (rc == NO_ERROR)
417 os2_formatmsg(msgbuf, msglen, reason);
418 else
419 sprintf(msgbuf, "unknown OS error #%d", errorcode);
420
421 return msgbuf;
422}
423
424/* Set an OS/2-specific error and return NULL. OS/2 kernel
425 errors are not in a global variable e.g. 'errno' nor are
426 they congruent with posix error numbers. */
427
428static PyObject * os2_error(int code)
429{
430 char text[1024];
431 PyObject *v;
432
433 os2_strerror(text, sizeof(text), code, "");
434
435 v = Py_BuildValue("(is)", code, text);
436 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000437 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000438 Py_DECREF(v);
439 }
440 return NULL; /* Signal to Python that an Exception is Pending */
441}
442
443#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000444
445/* POSIX generic methods */
446
Barry Warsaw53699e91996-12-10 23:23:01 +0000447static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000448posix_int(PyObject *args, char *format, int (*func)(int))
Guido van Rossum21142a01999-01-08 21:05:37 +0000449{
450 int fd;
451 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000452 if (!PyArg_ParseTuple(args, format, &fd))
Guido van Rossum21142a01999-01-08 21:05:37 +0000453 return NULL;
454 Py_BEGIN_ALLOW_THREADS
455 res = (*func)(fd);
456 Py_END_ALLOW_THREADS
457 if (res < 0)
458 return posix_error();
459 Py_INCREF(Py_None);
460 return Py_None;
461}
462
463
464static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000465posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000466{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000467 char *path1;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000468 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000469 if (!PyArg_ParseTuple(args, format, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000470 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000471 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000472 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000473 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000474 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000475 return posix_error_with_filename(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000476 Py_INCREF(Py_None);
477 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000478}
479
Barry Warsaw53699e91996-12-10 23:23:01 +0000480static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000481posix_2str(PyObject *args, char *format,
482 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000483{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000484 char *path1, *path2;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000485 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000486 if (!PyArg_ParseTuple(args, format, &path1, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000487 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000488 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000489 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000490 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000491 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000492 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000493 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000494 Py_INCREF(Py_None);
495 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000496}
497
Fred Drake699f3522000-06-29 21:12:41 +0000498/* pack a system stat C structure into the Python stat tuple
499 (used by posix_stat() and posix_fstat()) */
500static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000501_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000502{
503 PyObject *v = PyTuple_New(10);
504 if (v == NULL)
505 return NULL;
506
507 PyTuple_SetItem(v, 0, PyInt_FromLong((long)st.st_mode));
508#ifdef HAVE_LARGEFILE_SUPPORT
509 PyTuple_SetItem(v, 1, PyLong_FromLongLong((LONG_LONG)st.st_ino));
510#else
511 PyTuple_SetItem(v, 1, PyInt_FromLong((long)st.st_ino));
512#endif
513#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
514 PyTuple_SetItem(v, 2, PyLong_FromLongLong((LONG_LONG)st.st_dev));
515#else
516 PyTuple_SetItem(v, 2, PyInt_FromLong((long)st.st_dev));
517#endif
518 PyTuple_SetItem(v, 3, PyInt_FromLong((long)st.st_nlink));
519 PyTuple_SetItem(v, 4, PyInt_FromLong((long)st.st_uid));
520 PyTuple_SetItem(v, 5, PyInt_FromLong((long)st.st_gid));
521#ifdef HAVE_LARGEFILE_SUPPORT
522 PyTuple_SetItem(v, 6, PyLong_FromLongLong((LONG_LONG)st.st_size));
523#else
524 PyTuple_SetItem(v, 6, PyInt_FromLong(st.st_size));
525#endif
526#if SIZEOF_TIME_T > SIZEOF_LONG
527 PyTuple_SetItem(v, 7, PyLong_FromLongLong((LONG_LONG)st.st_atime));
528 PyTuple_SetItem(v, 8, PyLong_FromLongLong((LONG_LONG)st.st_mtime));
529 PyTuple_SetItem(v, 9, PyLong_FromLongLong((LONG_LONG)st.st_ctime));
530#else
531 PyTuple_SetItem(v, 7, PyInt_FromLong((long)st.st_atime));
532 PyTuple_SetItem(v, 8, PyInt_FromLong((long)st.st_mtime));
533 PyTuple_SetItem(v, 9, PyInt_FromLong((long)st.st_ctime));
534#endif
535
536 if (PyErr_Occurred()) {
537 Py_DECREF(v);
538 return NULL;
539 }
540
541 return v;
542}
543
544
Barry Warsaw53699e91996-12-10 23:23:01 +0000545static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000546posix_do_stat(PyObject *self, PyObject *args, char *format,
547 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000548{
Fred Drake699f3522000-06-29 21:12:41 +0000549 STRUCT_STAT st;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000550 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000551 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000552
553#ifdef MS_WIN32
554 int pathlen;
555 char pathcopy[MAX_PATH];
556#endif /* MS_WIN32 */
557
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000558 if (!PyArg_ParseTuple(args, format, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000559 return NULL;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000560
561#ifdef MS_WIN32
562 pathlen = strlen(path);
563 /* the library call can blow up if the file name is too long! */
564 if (pathlen > MAX_PATH) {
565 errno = ENAMETOOLONG;
566 return posix_error();
567 }
568
569 if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) {
Guido van Rossum19dde102000-05-03 02:44:55 +0000570 /* exception for specific or current drive root */
571 if (!((pathlen == 1) ||
572 ((pathlen == 3) &&
Guido van Rossumace88ae2000-04-21 18:54:45 +0000573 (path[1] == ':') &&
Guido van Rossum19dde102000-05-03 02:44:55 +0000574 (path[2] == '\\' || path[2] == '/'))))
Guido van Rossumace88ae2000-04-21 18:54:45 +0000575 {
576 strncpy(pathcopy, path, pathlen);
577 pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */
578 path = pathcopy;
579 }
580 }
581#endif /* MS_WIN32 */
582
Barry Warsaw53699e91996-12-10 23:23:01 +0000583 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000584 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000585 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000586 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000587 return posix_error_with_filename(path);
Fred Drake699f3522000-06-29 21:12:41 +0000588
589 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000590}
591
592
593/* POSIX methods */
594
Guido van Rossum94f6f721999-01-06 18:42:14 +0000595static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000596"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000597Test for access to a file.";
598
599static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000600posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000601{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000602 char *path;
603 int mode;
604 int res;
605
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000606 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000607 return NULL;
608 Py_BEGIN_ALLOW_THREADS
609 res = access(path, mode);
610 Py_END_ALLOW_THREADS
611 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000612}
613
Guido van Rossumd371ff11999-01-25 16:12:23 +0000614#ifndef F_OK
615#define F_OK 0
616#endif
617#ifndef R_OK
618#define R_OK 4
619#endif
620#ifndef W_OK
621#define W_OK 2
622#endif
623#ifndef X_OK
624#define X_OK 1
625#endif
626
627#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000628static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000629"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000630Return the name of the terminal device connected to 'fd'.";
631
632static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000633posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000634{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000635 int id;
636 char *ret;
637
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000638 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000639 return NULL;
640
Guido van Rossum94f6f721999-01-06 18:42:14 +0000641 ret = ttyname(id);
642 if (ret == NULL)
643 return(posix_error());
644 return(PyString_FromString(ret));
645}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000646#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000647
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000648#ifdef HAVE_CTERMID
649static char posix_ctermid__doc__[] =
650"ctermid() -> String\n\
651Return the name of the controlling terminal for this process.";
652
653static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000654posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000655{
656 char *ret;
657 char buffer[L_ctermid];
658
659 if (!PyArg_ParseTuple(args, ":ctermid"))
660 return NULL;
661
Greg Wardb48bc172000-03-01 21:51:56 +0000662#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000663 ret = ctermid_r(buffer);
664#else
665 ret = ctermid(buffer);
666#endif
667 if (ret == NULL)
668 return(posix_error());
669 return(PyString_FromString(buffer));
670}
671#endif
672
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000673static char posix_chdir__doc__[] =
674"chdir(path) -> None\n\
675Change the current working directory to the specified path.";
676
Barry Warsaw53699e91996-12-10 23:23:01 +0000677static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000678posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000679{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000680 return posix_1str(args, "s:chdir", chdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000681}
682
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000683
684static char posix_chmod__doc__[] =
685"chmod(path, mode) -> None\n\
686Change the access permissions of a file.";
687
Barry Warsaw53699e91996-12-10 23:23:01 +0000688static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000689posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000690{
Guido van Rossumffd15f52000-03-31 00:47:28 +0000691 char *path;
692 int i;
693 int res;
Guido van Rossum49679b42000-03-31 00:48:21 +0000694 if (!PyArg_ParseTuple(args, "si", &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000695 return NULL;
696 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000697 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000698 Py_END_ALLOW_THREADS
699 if (res < 0)
700 return posix_error_with_filename(path);
701 Py_INCREF(Py_None);
702 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000703}
704
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000705
Guido van Rossum21142a01999-01-08 21:05:37 +0000706#ifdef HAVE_FSYNC
707static char posix_fsync__doc__[] =
708"fsync(fildes) -> None\n\
709force write of file with filedescriptor to disk.";
710
711static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000712posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000713{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000714 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000715}
716#endif /* HAVE_FSYNC */
717
718#ifdef HAVE_FDATASYNC
719static char posix_fdatasync__doc__[] =
720"fdatasync(fildes) -> None\n\
721force write of file with filedescriptor to disk.\n\
722 does not force update of metadata.";
723
Guido van Rossum5d00b6d1999-01-08 21:28:05 +0000724extern int fdatasync(int); /* Prototype just in case */
725
Guido van Rossum21142a01999-01-08 21:05:37 +0000726static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000727posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000728{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000729 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000730}
731#endif /* HAVE_FDATASYNC */
732
733
Fredrik Lundh10723342000-07-10 16:38:09 +0000734#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000735static char posix_chown__doc__[] =
736"chown(path, uid, gid) -> None\n\
737Change the owner and group id of path to the numeric uid and gid.";
738
Barry Warsaw53699e91996-12-10 23:23:01 +0000739static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000740posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000741{
Fredrik Lundh44328e62000-07-10 15:59:30 +0000742 char *path;
743 int uid, gid;
744 int res;
745 if (!PyArg_ParseTuple(args, "sii:chown", &path, &uid, &gid))
746 return NULL;
747 Py_BEGIN_ALLOW_THREADS
748 res = chown(path, (uid_t) uid, (gid_t) gid);
749 Py_END_ALLOW_THREADS
750 if (res < 0)
751 return posix_error_with_filename(path);
752 Py_INCREF(Py_None);
753 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000754}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000755#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000756
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000757
Guido van Rossum36bc6801995-06-14 22:54:23 +0000758#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000759static char posix_getcwd__doc__[] =
760"getcwd() -> path\n\
761Return a string representing the current working directory.";
762
Barry Warsaw53699e91996-12-10 23:23:01 +0000763static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000764posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000765{
766 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000767 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000768 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000769 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000770 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000771 res = getcwd(buf, sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +0000772 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000773 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000774 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000775 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000776}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000777#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000778
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000779
Guido van Rossumb6775db1994-08-01 11:34:53 +0000780#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000781static char posix_link__doc__[] =
782"link(src, dst) -> None\n\
783Create a hard link to a file.";
784
Barry Warsaw53699e91996-12-10 23:23:01 +0000785static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000786posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000787{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000788 return posix_2str(args, "ss:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000789}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000790#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000791
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000792
793static char posix_listdir__doc__[] =
794"listdir(path) -> list_of_strings\n\
795Return a list containing the names of the entries in the directory.\n\
796\n\
797 path: path of directory to list\n\
798\n\
799The list is in arbitrary order. It does not include the special\n\
800entries '.' and '..' even if they are present in the directory.";
801
Barry Warsaw53699e91996-12-10 23:23:01 +0000802static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000803posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000804{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000805 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000806 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000807#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000808
Guido van Rossumb6775db1994-08-01 11:34:53 +0000809 char *name;
810 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000811 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000812 HANDLE hFindFile;
813 WIN32_FIND_DATA FileData;
814 char namebuf[MAX_PATH+5];
815
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000816 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000817 return NULL;
818 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000819 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000820 return NULL;
821 }
822 strcpy(namebuf, name);
823 if (namebuf[len-1] != '/' && namebuf[len-1] != '\\')
824 namebuf[len++] = '/';
825 strcpy(namebuf + len, "*.*");
826
Barry Warsaw53699e91996-12-10 23:23:01 +0000827 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000828 return NULL;
829
830 hFindFile = FindFirstFile(namebuf, &FileData);
831 if (hFindFile == INVALID_HANDLE_VALUE) {
832 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000833 if (errno == ERROR_FILE_NOT_FOUND)
834 return PyList_New(0);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000835 return win32_error("FindFirstFile", name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000836 }
837 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000838 if (FileData.cFileName[0] == '.' &&
839 (FileData.cFileName[1] == '\0' ||
840 FileData.cFileName[1] == '.' &&
841 FileData.cFileName[2] == '\0'))
842 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +0000843 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000844 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000845 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000846 d = NULL;
847 break;
848 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000849 if (PyList_Append(d, v) != 0) {
850 Py_DECREF(v);
851 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000852 d = NULL;
853 break;
854 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000855 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000856 } while (FindNextFile(hFindFile, &FileData) == TRUE);
857
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000858 if (FindClose(hFindFile) == FALSE)
859 return win32_error("FindClose", name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000860
861 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000862
Guido van Rossum8d665e61996-06-26 18:22:49 +0000863#else /* !MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000864#ifdef _MSC_VER /* 16-bit Windows */
865
866#ifndef MAX_PATH
867#define MAX_PATH 250
868#endif
869 char *name, *pt;
870 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000871 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000872 char namebuf[MAX_PATH+5];
873 struct _find_t ep;
874
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000875 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000876 return NULL;
877 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000878 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000879 return NULL;
880 }
881 strcpy(namebuf, name);
882 for (pt = namebuf; *pt; pt++)
883 if (*pt == '/')
884 *pt = '\\';
885 if (namebuf[len-1] != '\\')
886 namebuf[len++] = '\\';
887 strcpy(namebuf + len, "*.*");
888
Barry Warsaw53699e91996-12-10 23:23:01 +0000889 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000890 return NULL;
891
892 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +0000893 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
894 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000895 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000896 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000897 }
898 do {
899 if (ep.name[0] == '.' &&
900 (ep.name[1] == '\0' ||
901 ep.name[1] == '.' &&
902 ep.name[2] == '\0'))
903 continue;
904 strcpy(namebuf, ep.name);
905 for (pt = namebuf; *pt; pt++)
906 if (isupper(*pt))
907 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +0000908 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000909 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000910 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000911 d = NULL;
912 break;
913 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000914 if (PyList_Append(d, v) != 0) {
915 Py_DECREF(v);
916 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000917 d = NULL;
918 break;
919 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000920 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000921 } while (_dos_findnext(&ep) == 0);
922
923 return d;
924
925#else
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000926#if defined(PYOS_OS2)
927
928#ifndef MAX_PATH
929#define MAX_PATH CCHMAXPATH
930#endif
931 char *name, *pt;
932 int len;
933 PyObject *d, *v;
934 char namebuf[MAX_PATH+5];
935 HDIR hdir = 1;
936 ULONG srchcnt = 1;
937 FILEFINDBUF3 ep;
938 APIRET rc;
939
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000940 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000941 return NULL;
942 if (len >= MAX_PATH) {
943 PyErr_SetString(PyExc_ValueError, "path too long");
944 return NULL;
945 }
946 strcpy(namebuf, name);
947 for (pt = namebuf; *pt; pt++)
948 if (*pt == '/')
949 *pt = '\\';
950 if (namebuf[len-1] != '\\')
951 namebuf[len++] = '\\';
952 strcpy(namebuf + len, "*.*");
953
954 if ((d = PyList_New(0)) == NULL)
955 return NULL;
956
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000957 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
958 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000959 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000960 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
961 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
962 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000963
964 if (rc != NO_ERROR) {
965 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000966 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000967 }
968
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000969 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000970 do {
971 if (ep.achName[0] == '.'
972 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000973 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000974
975 strcpy(namebuf, ep.achName);
976
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000977 /* Leave Case of Name Alone -- In Native Form */
978 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000979
980 v = PyString_FromString(namebuf);
981 if (v == NULL) {
982 Py_DECREF(d);
983 d = NULL;
984 break;
985 }
986 if (PyList_Append(d, v) != 0) {
987 Py_DECREF(v);
988 Py_DECREF(d);
989 d = NULL;
990 break;
991 }
992 Py_DECREF(v);
993 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
994 }
995
996 return d;
997#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000998
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000999 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001000 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001001 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001002 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001003 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001004 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001005 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001006 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001007 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001008 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001009 closedir(dirp);
1010 return NULL;
1011 }
1012 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001013 if (ep->d_name[0] == '.' &&
1014 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001015 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001016 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001017 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001018 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001019 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001020 d = NULL;
1021 break;
1022 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001023 if (PyList_Append(d, v) != 0) {
1024 Py_DECREF(v);
1025 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001026 d = NULL;
1027 break;
1028 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001029 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001030 }
1031 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001032
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001033 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001034
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001035#endif /* !PYOS_OS2 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001036#endif /* !_MSC_VER */
Guido van Rossum8d665e61996-06-26 18:22:49 +00001037#endif /* !MS_WIN32 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001038}
1039
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001040static char posix_mkdir__doc__[] =
1041"mkdir(path [, mode=0777]) -> None\n\
1042Create a directory.";
1043
Barry Warsaw53699e91996-12-10 23:23:01 +00001044static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001045posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001046{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001047 int res;
1048 char *path;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001049 int mode = 0777;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001050 if (!PyArg_ParseTuple(args, "s|i:mkdir", &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001051 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001052 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001053#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001054 res = mkdir(path);
1055#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001056 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001057#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001058 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001059 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001060 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001061 Py_INCREF(Py_None);
1062 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001063}
1064
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001065
Guido van Rossumb6775db1994-08-01 11:34:53 +00001066#ifdef HAVE_NICE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001067static char posix_nice__doc__[] =
1068"nice(inc) -> new_priority\n\
1069Decrease the priority of process and return new priority.";
1070
Barry Warsaw53699e91996-12-10 23:23:01 +00001071static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001072posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001073{
1074 int increment, value;
1075
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001076 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001077 return NULL;
1078 value = nice(increment);
1079 if (value == -1)
1080 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001081 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001082}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001083#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001084
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001085
1086static char posix_rename__doc__[] =
1087"rename(old, new) -> None\n\
1088Rename a file or directory.";
1089
Barry Warsaw53699e91996-12-10 23:23:01 +00001090static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001091posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001092{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001093 return posix_2str(args, "ss:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001094}
1095
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001096
1097static char posix_rmdir__doc__[] =
1098"rmdir(path) -> None\n\
1099Remove a directory.";
1100
Barry Warsaw53699e91996-12-10 23:23:01 +00001101static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001102posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001103{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001104 return posix_1str(args, "s:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001105}
1106
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001107
1108static char posix_stat__doc__[] =
1109"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1110Perform a stat system call on the given path.";
1111
Barry Warsaw53699e91996-12-10 23:23:01 +00001112static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001113posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001114{
Fred Drake699f3522000-06-29 21:12:41 +00001115 return posix_do_stat(self, args, "s:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001116}
1117
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001118
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001119#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001120static char posix_system__doc__[] =
1121"system(command) -> exit_status\n\
1122Execute the command (a string) in a subshell.";
1123
Barry Warsaw53699e91996-12-10 23:23:01 +00001124static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001125posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001126{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001127 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001128 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001129 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001130 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001131 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001132 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001133 Py_END_ALLOW_THREADS
1134 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001135}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001136#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001137
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001138
1139static char posix_umask__doc__[] =
1140"umask(new_mask) -> old_mask\n\
1141Set the current numeric umask and return the previous umask.";
1142
Barry Warsaw53699e91996-12-10 23:23:01 +00001143static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001144posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001145{
1146 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001147 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001148 return NULL;
1149 i = umask(i);
1150 if (i < 0)
1151 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001152 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001153}
1154
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001155
1156static char posix_unlink__doc__[] =
1157"unlink(path) -> None\n\
1158Remove a file (same as remove(path)).";
1159
1160static char posix_remove__doc__[] =
1161"remove(path) -> None\n\
1162Remove a file (same as unlink(path)).";
1163
Barry Warsaw53699e91996-12-10 23:23:01 +00001164static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001165posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001166{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001167 return posix_1str(args, "s:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001168}
1169
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001170
Guido van Rossumb6775db1994-08-01 11:34:53 +00001171#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001172static char posix_uname__doc__[] =
1173"uname() -> (sysname, nodename, release, version, machine)\n\
1174Return a tuple identifying the current operating system.";
1175
Barry Warsaw53699e91996-12-10 23:23:01 +00001176static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001177posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001178{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001179 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001180 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001181 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001182 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001183 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001184 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001185 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001186 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001187 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001188 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001189 u.sysname,
1190 u.nodename,
1191 u.release,
1192 u.version,
1193 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001194}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001195#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001196
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001197
1198static char posix_utime__doc__[] =
1199"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001200utime(path, None) -> None\n\
1201Set the access and modified time of the file to the given values. If the\n\
1202second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001203
Barry Warsaw53699e91996-12-10 23:23:01 +00001204static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001205posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001206{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001207 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001208 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001209 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001210 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001211
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001212/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001213#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001214 struct utimbuf buf;
1215#define ATIME buf.actime
1216#define MTIME buf.modtime
1217#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001218#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001219 time_t buf[2];
1220#define ATIME buf[0]
1221#define MTIME buf[1]
1222#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001223#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001224
Barry Warsaw3cef8562000-05-01 16:17:24 +00001225 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001226 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001227 if (arg == Py_None) {
1228 /* optional time values not given */
1229 Py_BEGIN_ALLOW_THREADS
1230 res = utime(path, NULL);
1231 Py_END_ALLOW_THREADS
1232 }
1233 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1234 PyErr_SetString(PyExc_TypeError,
1235 "Second argument must be a 2-tuple of numbers.");
1236 return NULL;
1237 }
1238 else {
1239 ATIME = atime;
1240 MTIME = mtime;
1241 Py_BEGIN_ALLOW_THREADS
1242 res = utime(path, UTIME_ARG);
1243 Py_END_ALLOW_THREADS
1244 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001245 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001246 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001247 Py_INCREF(Py_None);
1248 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001249#undef UTIME_ARG
1250#undef ATIME
1251#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001252}
1253
Guido van Rossum85e3b011991-06-03 12:42:10 +00001254
Guido van Rossum3b066191991-06-04 19:40:25 +00001255/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001256
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001257static char posix__exit__doc__[] =
1258"_exit(status)\n\
1259Exit to the system with specified status, without normal exit processing.";
1260
Barry Warsaw53699e91996-12-10 23:23:01 +00001261static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001262posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001263{
1264 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001265 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001266 return NULL;
1267 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001268 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001269}
1270
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001271
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001272#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001273static char posix_execv__doc__[] =
1274"execv(path, args)\n\
1275Execute an executable path with arguments, replacing current process.\n\
1276\n\
1277 path: path of executable file\n\
1278 args: tuple or list of strings";
1279
Barry Warsaw53699e91996-12-10 23:23:01 +00001280static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001281posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001282{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001283 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001284 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001285 char **argvlist;
1286 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001287 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001288
Guido van Rossum89b33251993-10-22 14:26:06 +00001289 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001290 argv is a list or tuple of strings. */
1291
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001292 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001293 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001294 if (PyList_Check(argv)) {
1295 argc = PyList_Size(argv);
1296 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001297 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001298 else if (PyTuple_Check(argv)) {
1299 argc = PyTuple_Size(argv);
1300 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001301 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001302 else {
Guido van Rossum50422b42000-04-26 20:34:28 +00001303 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
1304 return NULL;
1305 }
1306
1307 if (argc == 0) {
1308 PyErr_SetString(PyExc_ValueError, "empty argument list");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001309 return NULL;
1310 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001311
Barry Warsaw53699e91996-12-10 23:23:01 +00001312 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001313 if (argvlist == NULL)
1314 return NULL;
1315 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001316 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1317 PyMem_DEL(argvlist);
Guido van Rossum50422b42000-04-26 20:34:28 +00001318 PyErr_SetString(PyExc_TypeError,
1319 "all arguments must be strings");
1320 return NULL;
1321
Guido van Rossum85e3b011991-06-03 12:42:10 +00001322 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001323 }
1324 argvlist[argc] = NULL;
1325
Guido van Rossumb6775db1994-08-01 11:34:53 +00001326#ifdef BAD_EXEC_PROTOTYPES
1327 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001328#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001329 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001330#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001331
Guido van Rossum85e3b011991-06-03 12:42:10 +00001332 /* If we get here it's definitely an error */
1333
Barry Warsaw53699e91996-12-10 23:23:01 +00001334 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001335 return posix_error();
1336}
1337
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001338
1339static char posix_execve__doc__[] =
1340"execve(path, args, env)\n\
1341Execute a path with arguments and environment, replacing current process.\n\
1342\n\
1343 path: path of executable file\n\
1344 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001345 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001346
Barry Warsaw53699e91996-12-10 23:23:01 +00001347static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001348posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001349{
1350 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001351 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001352 char **argvlist;
1353 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001354 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001355 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001356 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001357
1358 /* execve has three arguments: (path, argv, env), where
1359 argv is a list or tuple of strings and env is a dictionary
1360 like posix.environ. */
1361
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001362 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001363 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001364 if (PyList_Check(argv)) {
1365 argc = PyList_Size(argv);
1366 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001367 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001368 else if (PyTuple_Check(argv)) {
1369 argc = PyTuple_Size(argv);
1370 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001371 }
1372 else {
Barry Warsaw53699e91996-12-10 23:23:01 +00001373 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001374 return NULL;
1375 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001376 if (!PyMapping_Check(env)) {
1377 PyErr_SetString(PyExc_TypeError, "env must be mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001378 return NULL;
1379 }
1380
Guido van Rossum50422b42000-04-26 20:34:28 +00001381 if (argc == 0) {
1382 PyErr_SetString(PyExc_ValueError,
1383 "empty argument list");
1384 return NULL;
1385 }
1386
Barry Warsaw53699e91996-12-10 23:23:01 +00001387 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001388 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001389 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001390 return NULL;
1391 }
1392 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001393 if (!PyArg_Parse((*getitem)(argv, i),
Barry Warsaw43d68b81996-12-19 22:10:44 +00001394 "s;argv must be list of strings",
1395 &argvlist[i]))
1396 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001397 goto fail_1;
1398 }
1399 }
1400 argvlist[argc] = NULL;
1401
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001402 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001403 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001404 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001405 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001406 goto fail_1;
1407 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001408 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001409 keys = PyMapping_Keys(env);
1410 vals = PyMapping_Values(env);
1411 if (!keys || !vals)
1412 goto fail_2;
1413
1414 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001415 char *p, *k, *v;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001416
1417 key = PyList_GetItem(keys, pos);
1418 val = PyList_GetItem(vals, pos);
1419 if (!key || !val)
1420 goto fail_2;
1421
Barry Warsaw53699e91996-12-10 23:23:01 +00001422 if (!PyArg_Parse(key, "s;non-string key in env", &k) ||
Barry Warsaw43d68b81996-12-19 22:10:44 +00001423 !PyArg_Parse(val, "s;non-string value in env", &v))
1424 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001425 goto fail_2;
1426 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001427
1428#if defined(PYOS_OS2)
1429 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1430 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1431#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001432 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001433 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001434 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001435 goto fail_2;
1436 }
1437 sprintf(p, "%s=%s", k, v);
1438 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001439#if defined(PYOS_OS2)
1440 }
1441#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001442 }
1443 envlist[envc] = 0;
1444
Guido van Rossumb6775db1994-08-01 11:34:53 +00001445
1446#ifdef BAD_EXEC_PROTOTYPES
1447 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001448#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001449 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001450#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001451
1452 /* If we get here it's definitely an error */
1453
1454 (void) posix_error();
1455
1456 fail_2:
1457 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001458 PyMem_DEL(envlist[envc]);
1459 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001460 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001461 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001462 Py_XDECREF(vals);
1463 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001464 return NULL;
1465}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001466#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001467
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001468
Guido van Rossuma1065681999-01-25 23:20:23 +00001469#ifdef HAVE_SPAWNV
1470static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001471"spawnv(mode, path, args)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001472Execute an executable path with arguments, replacing current process.\n\
1473\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001474 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001475 path: path of executable file\n\
1476 args: tuple or list of strings";
1477
1478static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001479posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001480{
1481 char *path;
1482 PyObject *argv;
1483 char **argvlist;
1484 int mode, i, argc;
Fred Drake699f3522000-06-29 21:12:41 +00001485 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001486 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001487
1488 /* spawnv has three arguments: (mode, path, argv), where
1489 argv is a list or tuple of strings. */
1490
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001491 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001492 return NULL;
1493 if (PyList_Check(argv)) {
1494 argc = PyList_Size(argv);
1495 getitem = PyList_GetItem;
1496 }
1497 else if (PyTuple_Check(argv)) {
1498 argc = PyTuple_Size(argv);
1499 getitem = PyTuple_GetItem;
1500 }
1501 else {
Fred Drake137507e2000-06-01 02:02:46 +00001502 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001503 return NULL;
1504 }
1505
1506 argvlist = PyMem_NEW(char *, argc+1);
1507 if (argvlist == NULL)
1508 return NULL;
1509 for (i = 0; i < argc; i++) {
1510 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1511 PyMem_DEL(argvlist);
Fred Drake137507e2000-06-01 02:02:46 +00001512 PyErr_SetString(PyExc_TypeError,
1513 "all arguments must be strings");
1514 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001515 }
1516 }
1517 argvlist[argc] = NULL;
1518
Guido van Rossum246bc171999-02-01 23:54:31 +00001519 if (mode == _OLD_P_OVERLAY)
1520 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001521 spawnval = _spawnv(mode, path, argvlist);
Guido van Rossuma1065681999-01-25 23:20:23 +00001522
1523 PyMem_DEL(argvlist);
1524
Fred Drake699f3522000-06-29 21:12:41 +00001525 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001526 return posix_error();
1527 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001528#if SIZEOF_LONG == SIZEOF_VOID_P
1529 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001530#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001531 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001532#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001533}
1534
1535
1536static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001537"spawnve(mode, path, args, env)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001538Execute a path with arguments and environment, replacing current process.\n\
1539\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001540 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001541 path: path of executable file\n\
1542 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001543 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001544
1545static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001546posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001547{
1548 char *path;
1549 PyObject *argv, *env;
1550 char **argvlist;
1551 char **envlist;
1552 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1553 int mode, i, pos, argc, envc;
Fred Drake699f3522000-06-29 21:12:41 +00001554 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001555 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001556
1557 /* spawnve has four arguments: (mode, path, argv, env), where
1558 argv is a list or tuple of strings and env is a dictionary
1559 like posix.environ. */
1560
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001561 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001562 return NULL;
1563 if (PyList_Check(argv)) {
1564 argc = PyList_Size(argv);
1565 getitem = PyList_GetItem;
1566 }
1567 else if (PyTuple_Check(argv)) {
1568 argc = PyTuple_Size(argv);
1569 getitem = PyTuple_GetItem;
1570 }
1571 else {
1572 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
1573 return NULL;
1574 }
1575 if (!PyMapping_Check(env)) {
1576 PyErr_SetString(PyExc_TypeError, "env must be mapping object");
1577 return NULL;
1578 }
1579
1580 argvlist = PyMem_NEW(char *, argc+1);
1581 if (argvlist == NULL) {
1582 PyErr_NoMemory();
1583 return NULL;
1584 }
1585 for (i = 0; i < argc; i++) {
1586 if (!PyArg_Parse((*getitem)(argv, i),
1587 "s;argv must be list of strings",
1588 &argvlist[i]))
1589 {
1590 goto fail_1;
1591 }
1592 }
1593 argvlist[argc] = NULL;
1594
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001595 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001596 envlist = PyMem_NEW(char *, i + 1);
1597 if (envlist == NULL) {
1598 PyErr_NoMemory();
1599 goto fail_1;
1600 }
1601 envc = 0;
1602 keys = PyMapping_Keys(env);
1603 vals = PyMapping_Values(env);
1604 if (!keys || !vals)
1605 goto fail_2;
1606
1607 for (pos = 0; pos < i; pos++) {
1608 char *p, *k, *v;
1609
1610 key = PyList_GetItem(keys, pos);
1611 val = PyList_GetItem(vals, pos);
1612 if (!key || !val)
1613 goto fail_2;
1614
1615 if (!PyArg_Parse(key, "s;non-string key in env", &k) ||
1616 !PyArg_Parse(val, "s;non-string value in env", &v))
1617 {
1618 goto fail_2;
1619 }
1620 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1621 if (p == NULL) {
1622 PyErr_NoMemory();
1623 goto fail_2;
1624 }
1625 sprintf(p, "%s=%s", k, v);
1626 envlist[envc++] = p;
1627 }
1628 envlist[envc] = 0;
1629
Guido van Rossum246bc171999-02-01 23:54:31 +00001630 if (mode == _OLD_P_OVERLAY)
1631 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001632 spawnval = _spawnve(mode, path, argvlist, envlist);
1633 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001634 (void) posix_error();
1635 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001636#if SIZEOF_LONG == SIZEOF_VOID_P
1637 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001638#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001639 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001640#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001641
1642 fail_2:
1643 while (--envc >= 0)
1644 PyMem_DEL(envlist[envc]);
1645 PyMem_DEL(envlist);
1646 fail_1:
1647 PyMem_DEL(argvlist);
1648 Py_XDECREF(vals);
1649 Py_XDECREF(keys);
1650 return res;
1651}
1652#endif /* HAVE_SPAWNV */
1653
1654
Guido van Rossumad0ee831995-03-01 10:34:45 +00001655#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001656static char posix_fork__doc__[] =
1657"fork() -> pid\n\
1658Fork a child process.\n\
1659\n\
1660Return 0 to child process and PID of child to parent process.";
1661
Barry Warsaw53699e91996-12-10 23:23:01 +00001662static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001663posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001664{
1665 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001666 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001667 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001668 pid = fork();
1669 if (pid == -1)
1670 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001671 if (pid == 0)
1672 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001673 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001674}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001675#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001676
Fred Drake8cef4cf2000-06-28 16:40:38 +00001677#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1678#ifdef HAVE_PTY_H
1679#include <pty.h>
1680#else
1681#ifdef HAVE_LIBUTIL_H
1682#include <libutil.h>
1683#else
1684/* BSDI does not supply a prototype for the 'openpty' and 'forkpty'
Thomas Wouters7e474022000-07-16 12:04:32 +00001685 functions, even though they are included in libutil. */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001686#include <termios.h>
1687extern int openpty(int *, int *, char *, struct termios *, struct winsize *);
1688extern int forkpty(int *, char *, struct termios *, struct winsize *);
1689#endif /* HAVE_LIBUTIL_H */
1690#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001691#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001692
Thomas Wouters70c21a12000-07-14 14:28:33 +00001693#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001694static char posix_openpty__doc__[] =
1695"openpty() -> (master_fd, slave_fd)\n\
1696Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1697
1698static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001699posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001700{
1701 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001702#ifndef HAVE_OPENPTY
1703 char * slave_name;
1704 /* SGI apparently needs this forward declaration */
1705 extern char * _getpty(int *, int, mode_t, int);
1706#endif
1707
Fred Drake8cef4cf2000-06-28 16:40:38 +00001708 if (!PyArg_ParseTuple(args, ":openpty"))
1709 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001710
1711#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001712 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1713 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001714#else
1715 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1716 if (slave_name == NULL)
1717 return posix_error();
1718
1719 slave_fd = open(slave_name, O_RDWR);
1720 if (slave_fd < 0)
1721 return posix_error();
1722#endif /* defined(HAVE_OPENPTY) */
1723
Fred Drake8cef4cf2000-06-28 16:40:38 +00001724 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001725
Fred Drake8cef4cf2000-06-28 16:40:38 +00001726}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001727#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001728
1729#ifdef HAVE_FORKPTY
1730static char posix_forkpty__doc__[] =
1731"forkpty() -> (pid, master_fd)\n\
1732Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1733Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1734To both, return fd of newly opened pseudo-terminal.\n";
1735
1736static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001737posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001738{
1739 int master_fd, pid;
1740
1741 if (!PyArg_ParseTuple(args, ":forkpty"))
1742 return NULL;
1743 pid = forkpty(&master_fd, NULL, NULL, NULL);
1744 if (pid == -1)
1745 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001746 if (pid == 0)
1747 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001748 return Py_BuildValue("(ii)", pid, master_fd);
1749}
1750#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001751
Guido van Rossumad0ee831995-03-01 10:34:45 +00001752#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001753static char posix_getegid__doc__[] =
1754"getegid() -> egid\n\
1755Return the current process's effective group id.";
1756
Barry Warsaw53699e91996-12-10 23:23:01 +00001757static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001758posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001759{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001760 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001761 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001762 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001763}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001764#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001765
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001766
Guido van Rossumad0ee831995-03-01 10:34:45 +00001767#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001768static char posix_geteuid__doc__[] =
1769"geteuid() -> euid\n\
1770Return the current process's effective user id.";
1771
Barry Warsaw53699e91996-12-10 23:23:01 +00001772static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001773posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001774{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001775 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001776 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001777 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001778}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001779#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001780
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001781
Guido van Rossumad0ee831995-03-01 10:34:45 +00001782#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001783static char posix_getgid__doc__[] =
1784"getgid() -> gid\n\
1785Return the current process's group id.";
1786
Barry Warsaw53699e91996-12-10 23:23:01 +00001787static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001788posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001789{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001790 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001791 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001792 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001793}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001794#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001795
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001796
1797static char posix_getpid__doc__[] =
1798"getpid() -> pid\n\
1799Return the current process id";
1800
Barry Warsaw53699e91996-12-10 23:23:01 +00001801static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001802posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001803{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001804 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001805 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001806 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001807}
1808
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001809
Fred Drakec9680921999-12-13 16:37:25 +00001810#ifdef HAVE_GETGROUPS
1811static char posix_getgroups__doc__[] = "\
1812getgroups() -> list of group IDs\n\
1813Return list of supplemental group IDs for the process.";
1814
1815static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001816posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00001817{
1818 PyObject *result = NULL;
1819
1820 if (PyArg_ParseTuple(args, ":getgroups")) {
1821#ifdef NGROUPS_MAX
1822#define MAX_GROUPS NGROUPS_MAX
1823#else
1824 /* defined to be 16 on Solaris7, so this should be a small number */
1825#define MAX_GROUPS 64
1826#endif
1827 gid_t grouplist[MAX_GROUPS];
1828 int n;
1829
1830 n = getgroups(MAX_GROUPS, grouplist);
1831 if (n < 0)
1832 posix_error();
1833 else {
1834 result = PyList_New(n);
1835 if (result != NULL) {
1836 PyObject *o;
1837 int i;
1838 for (i = 0; i < n; ++i) {
1839 o = PyInt_FromLong((long)grouplist[i]);
1840 if (o == NULL) {
1841 Py_DECREF(result);
1842 result = NULL;
1843 break;
1844 }
1845 PyList_SET_ITEM(result, i, o);
1846 }
1847 }
1848 }
1849 }
1850 return result;
1851}
1852#endif
1853
Guido van Rossumb6775db1994-08-01 11:34:53 +00001854#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001855static char posix_getpgrp__doc__[] =
1856"getpgrp() -> pgrp\n\
1857Return the current process group id.";
1858
Barry Warsaw53699e91996-12-10 23:23:01 +00001859static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001860posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00001861{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001862 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00001863 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001864#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00001865 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001866#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00001867 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001868#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00001869}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001870#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00001871
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001872
Guido van Rossumb6775db1994-08-01 11:34:53 +00001873#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001874static char posix_setpgrp__doc__[] =
1875"setpgrp() -> None\n\
1876Make this process a session leader.";
1877
Barry Warsaw53699e91996-12-10 23:23:01 +00001878static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001879posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00001880{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001881 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00001882 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00001883#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00001884 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001885#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001886 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001887#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00001888 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001889 Py_INCREF(Py_None);
1890 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00001891}
1892
Guido van Rossumb6775db1994-08-01 11:34:53 +00001893#endif /* HAVE_SETPGRP */
1894
Guido van Rossumad0ee831995-03-01 10:34:45 +00001895#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001896static char posix_getppid__doc__[] =
1897"getppid() -> ppid\n\
1898Return the parent's process id.";
1899
Barry Warsaw53699e91996-12-10 23:23:01 +00001900static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001901posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001902{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001903 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001904 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001905 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001906}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001907#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001908
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001909
Fred Drake12c6e2d1999-12-14 21:25:03 +00001910#ifdef HAVE_GETLOGIN
1911static char posix_getlogin__doc__[] = "\
1912getlogin() -> string\n\
1913Return the actual login name.";
1914
1915static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001916posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00001917{
1918 PyObject *result = NULL;
1919
1920 if (PyArg_ParseTuple(args, ":getlogin")) {
1921 char *name = getlogin();
1922
1923 if (name == NULL)
1924 posix_error();
1925 else
1926 result = PyString_FromString(name);
1927 }
1928 return result;
1929}
1930#endif
1931
Guido van Rossumad0ee831995-03-01 10:34:45 +00001932#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001933static char posix_getuid__doc__[] =
1934"getuid() -> uid\n\
1935Return the current process's user id.";
1936
Barry Warsaw53699e91996-12-10 23:23:01 +00001937static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001938posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001939{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001940 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001941 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001942 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001943}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001944#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001945
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001946
Guido van Rossumad0ee831995-03-01 10:34:45 +00001947#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001948static char posix_kill__doc__[] =
1949"kill(pid, sig) -> None\n\
1950Kill a process with a signal.";
1951
Barry Warsaw53699e91996-12-10 23:23:01 +00001952static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001953posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001954{
1955 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001956 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001957 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001958#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001959 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
1960 APIRET rc;
1961 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001962 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001963
1964 } else if (sig == XCPT_SIGNAL_KILLPROC) {
1965 APIRET rc;
1966 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001967 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001968
1969 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001970 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001971#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00001972 if (kill(pid, sig) == -1)
1973 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001974#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001975 Py_INCREF(Py_None);
1976 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001977}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001978#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001979
Guido van Rossumc0125471996-06-28 18:55:32 +00001980#ifdef HAVE_PLOCK
1981
1982#ifdef HAVE_SYS_LOCK_H
1983#include <sys/lock.h>
1984#endif
1985
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001986static char posix_plock__doc__[] =
1987"plock(op) -> None\n\
1988Lock program segments into memory.";
1989
Barry Warsaw53699e91996-12-10 23:23:01 +00001990static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001991posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00001992{
1993 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001994 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00001995 return NULL;
1996 if (plock(op) == -1)
1997 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001998 Py_INCREF(Py_None);
1999 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002000}
2001#endif
2002
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002003
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002004#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002005static char posix_popen__doc__[] =
2006"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2007Open a pipe to/from a command returning a file object.";
2008
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002009#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002010static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002011async_system(const char *command)
2012{
2013 char *p, errormsg[256], args[1024];
2014 RESULTCODES rcodes;
2015 APIRET rc;
2016 char *shell = getenv("COMSPEC");
2017 if (!shell)
2018 shell = "cmd";
2019
2020 strcpy(args, shell);
2021 p = &args[ strlen(args)+1 ];
2022 strcpy(p, "/c ");
2023 strcat(p, command);
2024 p += strlen(p) + 1;
2025 *p = '\0';
2026
2027 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002028 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002029 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002030 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002031 &rcodes, shell);
2032 return rc;
2033}
2034
Guido van Rossumd48f2521997-12-05 22:19:34 +00002035static FILE *
2036popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002037{
2038 HFILE rhan, whan;
2039 FILE *retfd = NULL;
2040 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2041
Guido van Rossumd48f2521997-12-05 22:19:34 +00002042 if (rc != NO_ERROR) {
2043 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002044 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002045 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002046
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002047 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2048 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002049
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002050 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2051 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002052
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002053 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2054 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002055
2056 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002057 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002058 }
2059
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002060 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2061 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002062
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002063 close(oldfd); /* And Close Saved STDOUT Handle */
2064 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002065
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002066 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2067 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002068
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002069 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2070 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002071
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002072 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2073 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002074
2075 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002076 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002077 }
2078
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002079 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2080 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002081
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002082 close(oldfd); /* And Close Saved STDIN Handle */
2083 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002084
Guido van Rossumd48f2521997-12-05 22:19:34 +00002085 } else {
2086 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002087 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002088 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002089}
2090
2091static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002092posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002093{
2094 char *name;
2095 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002096 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002097 FILE *fp;
2098 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002099 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002100 return NULL;
2101 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002102 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002103 Py_END_ALLOW_THREADS
2104 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002105 return os2_error(err);
2106
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002107 f = PyFile_FromFile(fp, name, mode, fclose);
2108 if (f != NULL)
2109 PyFile_SetBufSize(f, bufsize);
2110 return f;
2111}
2112
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002113#elif defined(MS_WIN32)
2114
2115/*
2116 * Portable 'popen' replacement for Win32.
2117 *
2118 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2119 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Fredrik Lundh56055a42000-07-23 19:47:12 +00002120 * Return code handling by David Bolen.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002121 */
2122
2123#include <malloc.h>
2124#include <io.h>
2125#include <fcntl.h>
2126
2127/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2128#define POPEN_1 1
2129#define POPEN_2 2
2130#define POPEN_3 3
2131#define POPEN_4 4
2132
2133static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002134static int _PyPclose(FILE *file);
2135
2136/*
2137 * Internal dictionary mapping popen* file pointers to process handles,
2138 * in order to maintain a link to the process handle until the file is
2139 * closed, at which point the process exit code is returned to the caller.
2140 */
2141static PyObject *_PyPopenProcs = NULL;
2142
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002143
2144/* popen that works from a GUI.
2145 *
2146 * The result of this function is a pipe (file) connected to the
2147 * processes stdin or stdout, depending on the requested mode.
2148 */
2149
2150static PyObject *
2151posix_popen(PyObject *self, PyObject *args)
2152{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002153 PyObject *f, *s;
2154 int tm = 0;
2155
2156 char *cmdstring;
2157 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002158 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002159 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002160 return NULL;
2161
2162 s = PyTuple_New(0);
2163
2164 if (*mode == 'r')
2165 tm = _O_RDONLY;
2166 else if (*mode != 'w') {
2167 PyErr_SetString(PyExc_ValueError, "mode must be 'r' or 'w'");
2168 return NULL;
2169 } else
2170 tm = _O_WRONLY;
2171
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002172 if (bufsize != -1) {
2173 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2174 return NULL;
2175 }
2176
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002177 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002178 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002179 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002180 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002181 else
2182 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2183
2184 return f;
2185}
2186
2187/* Variation on win32pipe.popen
2188 *
2189 * The result of this function is a pipe (file) connected to the
2190 * process's stdin, and a pipe connected to the process's stdout.
2191 */
2192
2193static PyObject *
2194win32_popen2(PyObject *self, PyObject *args)
2195{
2196 PyObject *f;
2197 int tm=0;
2198
2199 char *cmdstring;
2200 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002201 int bufsize = -1;
2202 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002203 return NULL;
2204
2205 if (*mode == 't')
2206 tm = _O_TEXT;
2207 else if (*mode != 'b') {
2208 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2209 return NULL;
2210 } else
2211 tm = _O_BINARY;
2212
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002213 if (bufsize != -1) {
2214 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2215 return NULL;
2216 }
2217
2218 f = _PyPopen(cmdstring, tm, POPEN_2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002219
2220 return f;
2221}
2222
2223/*
2224 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002225 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002226 * The result of this function is 3 pipes - the process's stdin,
2227 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002228 */
2229
2230static PyObject *
2231win32_popen3(PyObject *self, PyObject *args)
2232{
2233 PyObject *f;
2234 int tm = 0;
2235
2236 char *cmdstring;
2237 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002238 int bufsize = -1;
2239 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002240 return NULL;
2241
2242 if (*mode == 't')
2243 tm = _O_TEXT;
2244 else if (*mode != 'b') {
2245 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2246 return NULL;
2247 } else
2248 tm = _O_BINARY;
2249
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002250 if (bufsize != -1) {
2251 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2252 return NULL;
2253 }
2254
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002255 f = _PyPopen(cmdstring, tm, POPEN_3);
2256
2257 return f;
2258}
2259
2260/*
2261 * Variation on win32pipe.popen
2262 *
2263 * The result of this function is 2 pipes - the processes stdin,
2264 * and stdout+stderr combined as a single pipe.
2265 */
2266
2267static PyObject *
2268win32_popen4(PyObject *self, PyObject *args)
2269{
2270 PyObject *f;
2271 int tm = 0;
2272
2273 char *cmdstring;
2274 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002275 int bufsize = -1;
2276 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002277 return NULL;
2278
2279 if (*mode == 't')
2280 tm = _O_TEXT;
2281 else if (*mode != 'b') {
2282 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2283 return NULL;
2284 } else
2285 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002286
2287 if (bufsize != -1) {
2288 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2289 return NULL;
2290 }
2291
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002292 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002293
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002294 return f;
2295}
2296
2297static int
Fredrik Lundh56055a42000-07-23 19:47:12 +00002298_PyPopenCreateProcess(char *cmdstring, FILE *file,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002299 HANDLE hStdin,
2300 HANDLE hStdout,
2301 HANDLE hStderr)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002302{
2303 PROCESS_INFORMATION piProcInfo;
2304 STARTUPINFO siStartInfo;
2305 char *s1,*s2, *s3 = " /c ";
2306 const char *szConsoleSpawn = "w9xpopen.exe \"";
2307 int i;
2308 int x;
2309
2310 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
2311 s1 = (char *)_alloca(i);
2312 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2313 return x;
2314 if (GetVersion() < 0x80000000) {
2315 /*
2316 * NT/2000
2317 */
2318 x = i + strlen(s3) + strlen(cmdstring) + 1;
2319 s2 = (char *)_alloca(x);
2320 ZeroMemory(s2, x);
2321 sprintf(s2, "%s%s%s", s1, s3, cmdstring);
2322 }
2323 else {
2324 /*
2325 * Oh gag, we're on Win9x. Use the workaround listed in
2326 * KB: Q150956
2327 */
2328 char modulepath[256];
2329 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2330 for (i = x = 0; modulepath[i]; i++)
2331 if (modulepath[i] == '\\')
2332 x = i+1;
2333 modulepath[x] = '\0';
2334 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2335 strlen(modulepath) +
2336 strlen(szConsoleSpawn) + 1;
2337 s2 = (char *)_alloca(x);
2338 ZeroMemory(s2, x);
2339 sprintf(
2340 s2,
2341 "%s%s%s%s%s\"",
2342 modulepath,
2343 szConsoleSpawn,
2344 s1,
2345 s3,
2346 cmdstring);
2347 }
2348 }
2349
2350 /* Could be an else here to try cmd.exe / command.com in the path
2351 Now we'll just error out.. */
2352 else
2353 return -1;
2354
2355 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2356 siStartInfo.cb = sizeof(STARTUPINFO);
2357 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2358 siStartInfo.hStdInput = hStdin;
2359 siStartInfo.hStdOutput = hStdout;
2360 siStartInfo.hStdError = hStderr;
2361 siStartInfo.wShowWindow = SW_HIDE;
2362
2363 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002364 s2,
2365 NULL,
2366 NULL,
2367 TRUE,
2368 CREATE_NEW_CONSOLE,
2369 NULL,
2370 NULL,
2371 &siStartInfo,
2372 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002373 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002374 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002375
2376 /*
2377 * Try to insert our process handle into the internal
2378 * dictionary so we can find it later when trying
2379 * to close this file.
2380 */
2381 if (!_PyPopenProcs)
2382 _PyPopenProcs = PyDict_New();
2383 if (_PyPopenProcs) {
2384 PyObject *hProcessObj, *fileObj;
2385
2386 hProcessObj = PyLong_FromVoidPtr(piProcInfo.hProcess);
2387 fileObj = PyLong_FromVoidPtr(file);
2388
2389 if (!hProcessObj || !fileObj ||
2390 PyDict_SetItem(_PyPopenProcs,
2391 fileObj, hProcessObj) < 0) {
2392 /* Insert failure - close handle to prevent leak */
2393 CloseHandle(piProcInfo.hProcess);
2394 }
2395 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002396 return TRUE;
2397 }
2398 return FALSE;
2399}
2400
2401/* The following code is based off of KB: Q190351 */
2402
2403static PyObject *
2404_PyPopen(char *cmdstring, int mode, int n)
2405{
2406 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2407 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
2408 hChildStderrRdDup; /* hChildStdoutWrDup; */
2409
2410 SECURITY_ATTRIBUTES saAttr;
2411 BOOL fSuccess;
2412 int fd1, fd2, fd3;
2413 FILE *f1, *f2, *f3;
2414 PyObject *f;
2415
2416 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2417 saAttr.bInheritHandle = TRUE;
2418 saAttr.lpSecurityDescriptor = NULL;
2419
2420 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2421 return win32_error("CreatePipe", NULL);
2422
2423 /* Create new output read handle and the input write handle. Set
2424 * the inheritance properties to FALSE. Otherwise, the child inherits
2425 * the these handles; resulting in non-closeable handles to the pipes
2426 * being created. */
2427 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002428 GetCurrentProcess(), &hChildStdinWrDup, 0,
2429 FALSE,
2430 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002431 if (!fSuccess)
2432 return win32_error("DuplicateHandle", NULL);
2433
2434 /* Close the inheritable version of ChildStdin
2435 that we're using. */
2436 CloseHandle(hChildStdinWr);
2437
2438 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2439 return win32_error("CreatePipe", NULL);
2440
2441 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002442 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2443 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002444 if (!fSuccess)
2445 return win32_error("DuplicateHandle", NULL);
2446
2447 /* Close the inheritable version of ChildStdout
2448 that we're using. */
2449 CloseHandle(hChildStdoutRd);
2450
2451 if (n != POPEN_4) {
2452 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2453 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002454 fSuccess = DuplicateHandle(GetCurrentProcess(),
2455 hChildStderrRd,
2456 GetCurrentProcess(),
2457 &hChildStderrRdDup, 0,
2458 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002459 if (!fSuccess)
2460 return win32_error("DuplicateHandle", NULL);
2461 /* Close the inheritable version of ChildStdErr that we're using. */
2462 CloseHandle(hChildStderrRd);
2463 }
2464
2465 switch (n) {
2466 case POPEN_1:
2467 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2468 case _O_WRONLY | _O_TEXT:
2469 /* Case for writing to child Stdin in text mode. */
2470 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2471 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002472 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002473 PyFile_SetBufSize(f, 0);
2474 /* We don't care about these pipes anymore, so close them. */
2475 CloseHandle(hChildStdoutRdDup);
2476 CloseHandle(hChildStderrRdDup);
2477 break;
2478
2479 case _O_RDONLY | _O_TEXT:
2480 /* Case for reading from child Stdout in text mode. */
2481 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2482 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002483 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002484 PyFile_SetBufSize(f, 0);
2485 /* We don't care about these pipes anymore, so close them. */
2486 CloseHandle(hChildStdinWrDup);
2487 CloseHandle(hChildStderrRdDup);
2488 break;
2489
2490 case _O_RDONLY | _O_BINARY:
2491 /* Case for readinig from child Stdout in binary mode. */
2492 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2493 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002494 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002495 PyFile_SetBufSize(f, 0);
2496 /* We don't care about these pipes anymore, so close them. */
2497 CloseHandle(hChildStdinWrDup);
2498 CloseHandle(hChildStderrRdDup);
2499 break;
2500
2501 case _O_WRONLY | _O_BINARY:
2502 /* Case for writing to child Stdin in binary mode. */
2503 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2504 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002505 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002506 PyFile_SetBufSize(f, 0);
2507 /* We don't care about these pipes anymore, so close them. */
2508 CloseHandle(hChildStdoutRdDup);
2509 CloseHandle(hChildStderrRdDup);
2510 break;
2511 }
2512 break;
2513
2514 case POPEN_2:
2515 case POPEN_4:
2516 {
2517 char *m1, *m2;
2518 PyObject *p1, *p2;
2519
2520 if (mode && _O_TEXT) {
2521 m1 = "r";
2522 m2 = "w";
2523 } else {
2524 m1 = "rb";
2525 m2 = "wb";
2526 }
2527
2528 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2529 f1 = _fdopen(fd1, m2);
2530 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2531 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002532 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002533 PyFile_SetBufSize(p1, 0);
2534 p2 = PyFile_FromFile(f2, cmdstring, m1, fclose);
2535 PyFile_SetBufSize(p2, 0);
2536
2537 if (n != 4)
2538 CloseHandle(hChildStderrRdDup);
2539
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002540 f = Py_BuildValue("OO",p1,p2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002541 break;
2542 }
2543
2544 case POPEN_3:
2545 {
2546 char *m1, *m2;
2547 PyObject *p1, *p2, *p3;
2548
2549 if (mode && _O_TEXT) {
2550 m1 = "r";
2551 m2 = "w";
2552 } else {
2553 m1 = "rb";
2554 m2 = "wb";
2555 }
2556
2557 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2558 f1 = _fdopen(fd1, m2);
2559 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2560 f2 = _fdopen(fd2, m1);
2561 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2562 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002563 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002564 p2 = PyFile_FromFile(f2, cmdstring, m1, fclose);
2565 p3 = PyFile_FromFile(f3, cmdstring, m1, fclose);
2566 PyFile_SetBufSize(p1, 0);
2567 PyFile_SetBufSize(p2, 0);
2568 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002569 f = Py_BuildValue("OOO",p1,p2,p3);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002570 break;
2571 }
2572 }
2573
2574 if (n == POPEN_4) {
2575 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh56055a42000-07-23 19:47:12 +00002576 f1,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002577 hChildStdinRd,
2578 hChildStdoutWr,
2579 hChildStdoutWr))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002580 return win32_error("CreateProcess", NULL);
2581 }
2582 else {
2583 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh56055a42000-07-23 19:47:12 +00002584 f1,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002585 hChildStdinRd,
2586 hChildStdoutWr,
2587 hChildStderrWr))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002588 return win32_error("CreateProcess", NULL);
2589 }
2590
2591 /* Child is launched. Close the parents copy of those pipe
2592 * handles that only the child should have open. You need to
2593 * make sure that no handles to the write end of the output pipe
2594 * are maintained in this process or else the pipe will not close
2595 * when the child process exits and the ReadFile will hang. */
2596
2597 if (!CloseHandle(hChildStdinRd))
2598 return win32_error("CloseHandle", NULL);
2599
2600 if (!CloseHandle(hChildStdoutWr))
2601 return win32_error("CloseHandle", NULL);
2602
2603 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2604 return win32_error("CloseHandle", NULL);
2605
2606 return f;
2607}
Fredrik Lundh56055a42000-07-23 19:47:12 +00002608
2609/*
2610 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2611 * exit code for the child process and return as a result of the close.
2612 */
2613static int _PyPclose(FILE *file)
2614{
2615 int result = 0;
2616 DWORD exit_code;
2617 HANDLE hProcess;
2618 PyObject *hProcessObj, *fileObj;
2619
2620 if (_PyPopenProcs) {
2621 fileObj = PyLong_FromVoidPtr(file);
2622 if (fileObj) {
2623 hProcessObj = PyDict_GetItem(_PyPopenProcs, fileObj);
2624 if (hProcessObj) {
2625 hProcess = PyLong_AsVoidPtr(hProcessObj);
2626 if (GetExitCodeProcess(hProcess, &exit_code)) {
2627 /* Possible truncation here in 16-bit environments, but
2628 * real exit codes are just the lower byte in any event.
2629 */
2630 result = exit_code;
2631 if (result == STILL_ACTIVE)
2632 result = 0; /* Minimize confusion */
2633 } else {
2634 /* No good way to bubble up an error, so instead we just
2635 * return the Windows last error shifted above standard
2636 * exit codes. This will truncate in 16-bits but should
2637 * be fine in 32 and at least distinguishes the problem.
2638 */
2639 result = (GetLastError() << 8);
2640 }
2641
2642 /* Free up the native handle at this point */
2643 CloseHandle(hProcess);
2644
2645 /* Remove from dictionary and flush dictionary if empty */
2646 PyDict_DelItem(_PyPopenProcs, fileObj);
2647 if (PyDict_Size(_PyPopenProcs) == 0) {
2648 Py_DECREF(_PyPopenProcs);
2649 _PyPopenProcs = NULL;
2650 }
2651 } /* if hProcessObj */
2652 } /* if fileObj */
2653 } /* if _PyPopenProcs */
2654
2655 fclose(file);
2656 return result;
2657}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002658#else
Barry Warsaw53699e91996-12-10 23:23:01 +00002659static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002660posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00002661{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002662 char *name;
2663 char *mode = "r";
2664 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00002665 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00002666 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002667 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00002668 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002669 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002670 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00002671 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00002672 if (fp == NULL)
2673 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002674 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002675 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00002676 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002677 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00002678}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002679#endif
2680
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002681#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00002682
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002683
Guido van Rossumb6775db1994-08-01 11:34:53 +00002684#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002685static char posix_setuid__doc__[] =
2686"setuid(uid) -> None\n\
2687Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00002688static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002689posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002690{
2691 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002692 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002693 return NULL;
2694 if (setuid(uid) < 0)
2695 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002696 Py_INCREF(Py_None);
2697 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002698}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002699#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002700
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002701
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00002702#ifdef HAVE_SETEUID
2703static char posix_seteuid__doc__[] =
2704"seteuid(uid) -> None\n\
2705Set the current process's effective user id.";
2706static PyObject *
2707posix_seteuid (PyObject *self, PyObject *args)
2708{
2709 int euid;
2710 if (!PyArg_ParseTuple(args, "i", &euid)) {
2711 return NULL;
2712 } else if (seteuid(euid) < 0) {
2713 return posix_error();
2714 } else {
2715 Py_INCREF(Py_None);
2716 return Py_None;
2717 }
2718}
2719#endif /* HAVE_SETEUID */
2720
2721#ifdef HAVE_SETEGID
2722static char posix_setegid__doc__[] =
2723"setegid(gid) -> None\n\
2724Set the current process's effective group id.";
2725static PyObject *
2726posix_setegid (PyObject *self, PyObject *args)
2727{
2728 int egid;
2729 if (!PyArg_ParseTuple(args, "i", &egid)) {
2730 return NULL;
2731 } else if (setegid(egid) < 0) {
2732 return posix_error();
2733 } else {
2734 Py_INCREF(Py_None);
2735 return Py_None;
2736 }
2737}
2738#endif /* HAVE_SETEGID */
2739
2740#ifdef HAVE_SETREUID
2741static char posix_setreuid__doc__[] =
2742"seteuid(ruid, euid) -> None\n\
2743Set the current process's real and effective user ids.";
2744static PyObject *
2745posix_setreuid (PyObject *self, PyObject *args)
2746{
2747 int ruid, euid;
2748 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
2749 return NULL;
2750 } else if (setreuid(ruid, euid) < 0) {
2751 return posix_error();
2752 } else {
2753 Py_INCREF(Py_None);
2754 return Py_None;
2755 }
2756}
2757#endif /* HAVE_SETREUID */
2758
2759#ifdef HAVE_SETREGID
2760static char posix_setregid__doc__[] =
2761"setegid(rgid, egid) -> None\n\
2762Set the current process's real and effective group ids.";
2763static PyObject *
2764posix_setregid (PyObject *self, PyObject *args)
2765{
2766 int rgid, egid;
2767 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
2768 return NULL;
2769 } else if (setregid(rgid, egid) < 0) {
2770 return posix_error();
2771 } else {
2772 Py_INCREF(Py_None);
2773 return Py_None;
2774 }
2775}
2776#endif /* HAVE_SETREGID */
2777
Guido van Rossumb6775db1994-08-01 11:34:53 +00002778#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002779static char posix_setgid__doc__[] =
2780"setgid(gid) -> None\n\
2781Set the current process's group id.";
2782
Barry Warsaw53699e91996-12-10 23:23:01 +00002783static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002784posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002785{
2786 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002787 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002788 return NULL;
2789 if (setgid(gid) < 0)
2790 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002791 Py_INCREF(Py_None);
2792 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002793}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002794#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002795
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002796
Guido van Rossumb6775db1994-08-01 11:34:53 +00002797#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002798static char posix_waitpid__doc__[] =
2799"waitpid(pid, options) -> (pid, status)\n\
2800Wait for completion of a give child process.";
2801
Barry Warsaw53699e91996-12-10 23:23:01 +00002802static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002803posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002804{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002805 int pid, options;
2806#ifdef UNION_WAIT
2807 union wait status;
2808#define status_i (status.w_status)
2809#else
2810 int status;
2811#define status_i status
2812#endif
2813 status_i = 0;
2814
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002815 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00002816 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002817 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00002818#ifdef NeXT
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002819 pid = wait4(pid, &status, options, NULL);
Guido van Rossume6a3aa61999-02-01 16:15:30 +00002820#else
2821 pid = waitpid(pid, &status, options);
2822#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002823 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00002824 if (pid == -1)
2825 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00002826 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002827 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00002828}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002829#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +00002830
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002831
Guido van Rossumad0ee831995-03-01 10:34:45 +00002832#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002833static char posix_wait__doc__[] =
2834"wait() -> (pid, status)\n\
2835Wait for completion of a child process.";
2836
Barry Warsaw53699e91996-12-10 23:23:01 +00002837static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002838posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00002839{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002840 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002841#ifdef UNION_WAIT
2842 union wait status;
2843#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00002844#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002845 int status;
2846#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00002847#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002848 if (!PyArg_ParseTuple(args, ":wait"))
2849 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002850 status_i = 0;
2851 Py_BEGIN_ALLOW_THREADS
2852 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00002853 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00002854 if (pid == -1)
2855 return posix_error();
2856 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002857 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002858#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00002859}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002860#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002861
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002862
2863static char posix_lstat__doc__[] =
2864"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
2865Like stat(path), but do not follow symbolic links.";
2866
Barry Warsaw53699e91996-12-10 23:23:01 +00002867static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002868posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002869{
Guido van Rossumb6775db1994-08-01 11:34:53 +00002870#ifdef HAVE_LSTAT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002871 return posix_do_stat(self, args, "s:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002872#else /* !HAVE_LSTAT */
Fred Drake699f3522000-06-29 21:12:41 +00002873 return posix_do_stat(self, args, "s:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002874#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002875}
2876
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002877
Guido van Rossumb6775db1994-08-01 11:34:53 +00002878#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002879static char posix_readlink__doc__[] =
2880"readlink(path) -> path\n\
2881Return a string representing the path to which the symbolic link points.";
2882
Barry Warsaw53699e91996-12-10 23:23:01 +00002883static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002884posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002885{
Guido van Rossumb6775db1994-08-01 11:34:53 +00002886 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002887 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002888 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002889 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002890 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002891 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00002892 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00002893 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002894 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00002895 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002896 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002897}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002898#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002899
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002900
Guido van Rossumb6775db1994-08-01 11:34:53 +00002901#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002902static char posix_symlink__doc__[] =
2903"symlink(src, dst) -> None\n\
2904Create a symbolic link.";
2905
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002906static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002907posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002908{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002909 return posix_2str(args, "ss:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002910}
2911#endif /* HAVE_SYMLINK */
2912
2913
2914#ifdef HAVE_TIMES
2915#ifndef HZ
2916#define HZ 60 /* Universal constant :-) */
2917#endif /* HZ */
2918
Guido van Rossumd48f2521997-12-05 22:19:34 +00002919#if defined(PYCC_VACPP) && defined(PYOS_OS2)
2920static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002921system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002922{
2923 ULONG value = 0;
2924
2925 Py_BEGIN_ALLOW_THREADS
2926 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
2927 Py_END_ALLOW_THREADS
2928
2929 return value;
2930}
2931
2932static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002933posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002934{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002935 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00002936 return NULL;
2937
2938 /* Currently Only Uptime is Provided -- Others Later */
2939 return Py_BuildValue("ddddd",
2940 (double)0 /* t.tms_utime / HZ */,
2941 (double)0 /* t.tms_stime / HZ */,
2942 (double)0 /* t.tms_cutime / HZ */,
2943 (double)0 /* t.tms_cstime / HZ */,
2944 (double)system_uptime() / 1000);
2945}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002946#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00002947static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002948posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00002949{
2950 struct tms t;
2951 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002952 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00002953 return NULL;
2954 errno = 0;
2955 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00002956 if (c == (clock_t) -1)
2957 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002958 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002959 (double)t.tms_utime / HZ,
2960 (double)t.tms_stime / HZ,
2961 (double)t.tms_cutime / HZ,
2962 (double)t.tms_cstime / HZ,
2963 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00002964}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002965#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002966#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002967
2968
Guido van Rossum87755a21996-09-07 00:59:43 +00002969#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00002970#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00002971static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002972posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00002973{
2974 FILETIME create, exit, kernel, user;
2975 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002976 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00002977 return NULL;
2978 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00002979 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
2980 /* The fields of a FILETIME structure are the hi and lo part
2981 of a 64-bit value expressed in 100 nanosecond units.
2982 1e7 is one second in such units; 1e-7 the inverse.
2983 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
2984 */
Barry Warsaw53699e91996-12-10 23:23:01 +00002985 return Py_BuildValue(
2986 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00002987 (double)(kernel.dwHighDateTime*429.4967296 +
2988 kernel.dwLowDateTime*1e-7),
2989 (double)(user.dwHighDateTime*429.4967296 +
2990 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00002991 (double)0,
2992 (double)0,
2993 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00002994}
Guido van Rossum8d665e61996-06-26 18:22:49 +00002995#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002996
2997#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00002998static char posix_times__doc__[] =
2999"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
3000Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003001#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003002
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003003
Guido van Rossumb6775db1994-08-01 11:34:53 +00003004#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003005static char posix_setsid__doc__[] =
3006"setsid() -> None\n\
3007Call the system call setsid().";
3008
Barry Warsaw53699e91996-12-10 23:23:01 +00003009static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003010posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003011{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003012 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003013 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003014 if (setsid() < 0)
3015 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003016 Py_INCREF(Py_None);
3017 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003018}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003019#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003020
Guido van Rossumb6775db1994-08-01 11:34:53 +00003021#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003022static char posix_setpgid__doc__[] =
3023"setpgid(pid, pgrp) -> None\n\
3024Call the system call setpgid().";
3025
Barry Warsaw53699e91996-12-10 23:23:01 +00003026static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003027posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003028{
3029 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003030 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003031 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003032 if (setpgid(pid, pgrp) < 0)
3033 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003034 Py_INCREF(Py_None);
3035 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003036}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003037#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003038
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003039
Guido van Rossumb6775db1994-08-01 11:34:53 +00003040#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003041static char posix_tcgetpgrp__doc__[] =
3042"tcgetpgrp(fd) -> pgid\n\
3043Return the process group associated with the terminal given by a fd.";
3044
Barry Warsaw53699e91996-12-10 23:23:01 +00003045static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003046posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003047{
3048 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003049 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003050 return NULL;
3051 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003052 if (pgid < 0)
3053 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003054 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00003055}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003056#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00003057
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003058
Guido van Rossumb6775db1994-08-01 11:34:53 +00003059#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003060static char posix_tcsetpgrp__doc__[] =
3061"tcsetpgrp(fd, pgid) -> None\n\
3062Set the process group associated with the terminal given by a fd.";
3063
Barry Warsaw53699e91996-12-10 23:23:01 +00003064static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003065posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003066{
3067 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003068 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003069 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003070 if (tcsetpgrp(fd, pgid) < 0)
3071 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00003072 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00003073 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00003074}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003075#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00003076
Guido van Rossum687dd131993-05-17 08:34:16 +00003077/* Functions acting on file descriptors */
3078
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003079static char posix_open__doc__[] =
3080"open(filename, flag [, mode=0777]) -> fd\n\
3081Open a file (for low level IO).";
3082
Barry Warsaw53699e91996-12-10 23:23:01 +00003083static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003084posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003085{
3086 char *file;
3087 int flag;
3088 int mode = 0777;
3089 int fd;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003090 if (!PyArg_ParseTuple(args, "si|i", &file, &flag, &mode))
3091 return NULL;
3092
Barry Warsaw53699e91996-12-10 23:23:01 +00003093 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003094 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003095 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003096 if (fd < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003097 return posix_error_with_filename(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00003098 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003099}
3100
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003101
3102static char posix_close__doc__[] =
3103"close(fd) -> None\n\
3104Close a file descriptor (for low level IO).";
3105
Barry Warsaw53699e91996-12-10 23:23:01 +00003106static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003107posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003108{
3109 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003110 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003111 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003112 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003113 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003114 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003115 if (res < 0)
3116 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003117 Py_INCREF(Py_None);
3118 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003119}
3120
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003121
3122static char posix_dup__doc__[] =
3123"dup(fd) -> fd2\n\
3124Return a duplicate of a file descriptor.";
3125
Barry Warsaw53699e91996-12-10 23:23:01 +00003126static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003127posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003128{
3129 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003130 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003131 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003132 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003133 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003134 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003135 if (fd < 0)
3136 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003137 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003138}
3139
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003140
3141static char posix_dup2__doc__[] =
3142"dup2(fd, fd2) -> None\n\
3143Duplicate file descriptor.";
3144
Barry Warsaw53699e91996-12-10 23:23:01 +00003145static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003146posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003147{
3148 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003149 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00003150 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003151 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003152 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00003153 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003154 if (res < 0)
3155 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003156 Py_INCREF(Py_None);
3157 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003158}
3159
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003160
3161static char posix_lseek__doc__[] =
3162"lseek(fd, pos, how) -> newpos\n\
3163Set the current position of a file descriptor.";
3164
Barry Warsaw53699e91996-12-10 23:23:01 +00003165static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003166posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003167{
3168 int fd, how;
Fred Drake699f3522000-06-29 21:12:41 +00003169#ifdef MS_WIN64
3170 LONG_LONG pos, res;
3171#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003172 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003173#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003174 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003175 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003176 return NULL;
3177#ifdef SEEK_SET
3178 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3179 switch (how) {
3180 case 0: how = SEEK_SET; break;
3181 case 1: how = SEEK_CUR; break;
3182 case 2: how = SEEK_END; break;
3183 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003184#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003185
3186#if !defined(HAVE_LARGEFILE_SUPPORT)
3187 pos = PyInt_AsLong(posobj);
3188#else
3189 pos = PyLong_Check(posobj) ?
3190 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3191#endif
3192 if (PyErr_Occurred())
3193 return NULL;
3194
Barry Warsaw53699e91996-12-10 23:23:01 +00003195 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003196#ifdef MS_WIN64
3197 res = _lseeki64(fd, pos, how);
3198#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003199 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003200#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003201 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003202 if (res < 0)
3203 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003204
3205#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003206 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003207#else
3208 return PyLong_FromLongLong(res);
3209#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003210}
3211
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003212
3213static char posix_read__doc__[] =
3214"read(fd, buffersize) -> string\n\
3215Read a file descriptor.";
3216
Barry Warsaw53699e91996-12-10 23:23:01 +00003217static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003218posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003219{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003220 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003221 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003222 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003223 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003224 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003225 if (buffer == NULL)
3226 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003227 Py_BEGIN_ALLOW_THREADS
3228 n = read(fd, PyString_AsString(buffer), size);
3229 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003230 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003231 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003232 return posix_error();
3233 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003234 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003235 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003236 return buffer;
3237}
3238
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003239
3240static char posix_write__doc__[] =
3241"write(fd, string) -> byteswritten\n\
3242Write a string to a file descriptor.";
3243
Barry Warsaw53699e91996-12-10 23:23:01 +00003244static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003245posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003246{
3247 int fd, size;
3248 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003249 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003250 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003251 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003252 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003253 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003254 if (size < 0)
3255 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003256 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003257}
3258
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003259
3260static char posix_fstat__doc__[]=
3261"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3262Like stat(), but for an open file descriptor.";
3263
Barry Warsaw53699e91996-12-10 23:23:01 +00003264static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003265posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003266{
3267 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003268 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003269 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003270 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003271 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003272 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003273 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003274 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003275 if (res != 0)
3276 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00003277
3278 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003279}
3280
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003281
3282static char posix_fdopen__doc__[] =
3283"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3284Return an open file object connected to a file descriptor.";
3285
Barry Warsaw53699e91996-12-10 23:23:01 +00003286static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003287posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003288{
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003289 extern int fclose(FILE *);
Guido van Rossum687dd131993-05-17 08:34:16 +00003290 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003291 char *mode = "r";
3292 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003293 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003294 PyObject *f;
3295 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003296 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003297
Barry Warsaw53699e91996-12-10 23:23:01 +00003298 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003299 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003300 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003301 if (fp == NULL)
3302 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003303 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003304 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003305 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003306 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003307}
3308
Skip Montanaro1517d842000-07-19 14:34:14 +00003309static char posix_isatty__doc__[] =
3310"isatty(fd) -> Boolean\n\
3311Return true if the file descriptor 'fd' is an open file descriptor\n\
3312connected to a terminal.";
3313
3314static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00003315posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00003316{
3317 int fd;
3318 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3319 return NULL;
3320 return Py_BuildValue("i", isatty(fd));
3321}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003322
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003323#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003324static char posix_pipe__doc__[] =
3325"pipe() -> (read_end, write_end)\n\
3326Create a pipe.";
3327
Barry Warsaw53699e91996-12-10 23:23:01 +00003328static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003329posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003330{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003331#if defined(PYOS_OS2)
3332 HFILE read, write;
3333 APIRET rc;
3334
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003335 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003336 return NULL;
3337
3338 Py_BEGIN_ALLOW_THREADS
3339 rc = DosCreatePipe( &read, &write, 4096);
3340 Py_END_ALLOW_THREADS
3341 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003342 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003343
3344 return Py_BuildValue("(ii)", read, write);
3345#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003346#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003347 int fds[2];
3348 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003349 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003350 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003351 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003352 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003353 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003354 if (res != 0)
3355 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003356 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003357#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003358 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003359 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003360 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003361 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003362 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003363 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003364 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003365 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003366 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003367 return win32_error("CreatePipe", NULL);
Fred Drake699f3522000-06-29 21:12:41 +00003368 read_fd = _open_osfhandle((intptr_t)read, 0);
3369 write_fd = _open_osfhandle((intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003370 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003371#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003372#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003373}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003374#endif /* HAVE_PIPE */
3375
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003376
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003377#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003378static char posix_mkfifo__doc__[] =
3379"mkfifo(file, [, mode=0666]) -> None\n\
3380Create a FIFO (a POSIX named pipe).";
3381
Barry Warsaw53699e91996-12-10 23:23:01 +00003382static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003383posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003384{
3385 char *file;
3386 int mode = 0666;
3387 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003388 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003389 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003390 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003391 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003392 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003393 if (res < 0)
3394 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003395 Py_INCREF(Py_None);
3396 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003397}
3398#endif
3399
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003400
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003401#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003402static char posix_ftruncate__doc__[] =
3403"ftruncate(fd, length) -> None\n\
3404Truncate a file to a specified length.";
3405
Barry Warsaw53699e91996-12-10 23:23:01 +00003406static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003407posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003408{
3409 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003410 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003411 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003412 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003413
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003414 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003415 return NULL;
3416
3417#if !defined(HAVE_LARGEFILE_SUPPORT)
3418 length = PyInt_AsLong(lenobj);
3419#else
3420 length = PyLong_Check(lenobj) ?
3421 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3422#endif
3423 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003424 return NULL;
3425
Barry Warsaw53699e91996-12-10 23:23:01 +00003426 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003427 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003428 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003429 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003430 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003431 return NULL;
3432 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003433 Py_INCREF(Py_None);
3434 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003435}
3436#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003437
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003438#ifdef NeXT
3439#define HAVE_PUTENV
3440/* Steve Spicklemire got this putenv from NeXTAnswers */
3441static int
3442putenv(char *newval)
3443{
3444 extern char **environ;
3445
3446 static int firstTime = 1;
3447 char **ep;
3448 char *cp;
3449 int esiz;
3450 char *np;
3451
3452 if (!(np = strchr(newval, '=')))
3453 return 1;
3454 *np = '\0';
3455
3456 /* look it up */
3457 for (ep=environ ; *ep ; ep++)
3458 {
3459 /* this should always be true... */
3460 if (cp = strchr(*ep, '='))
3461 {
3462 *cp = '\0';
3463 if (!strcmp(*ep, newval))
3464 {
3465 /* got it! */
3466 *cp = '=';
3467 break;
3468 }
3469 *cp = '=';
3470 }
3471 else
3472 {
3473 *np = '=';
3474 return 1;
3475 }
3476 }
3477
3478 *np = '=';
3479 if (*ep)
3480 {
3481 /* the string was already there:
3482 just replace it with the new one */
3483 *ep = newval;
3484 return 0;
3485 }
3486
3487 /* expand environ by one */
3488 for (esiz=2, ep=environ ; *ep ; ep++)
3489 esiz++;
3490 if (firstTime)
3491 {
3492 char **epp;
3493 char **newenv;
3494 if (!(newenv = malloc(esiz * sizeof(char *))))
3495 return 1;
3496
3497 for (ep=environ, epp=newenv ; *ep ;)
3498 *epp++ = *ep++;
3499 *epp++ = newval;
3500 *epp = (char *) 0;
3501 environ = newenv;
3502 }
3503 else
3504 {
3505 if (!(environ = realloc(environ, esiz * sizeof(char *))))
3506 return 1;
3507 environ[esiz - 2] = newval;
3508 environ[esiz - 1] = (char *) 0;
3509 firstTime = 0;
3510 }
3511
3512 return 0;
3513}
Guido van Rossumc6ef2041997-08-21 02:30:45 +00003514#endif /* NeXT */
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003515
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003516
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003517#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003518static char posix_putenv__doc__[] =
3519"putenv(key, value) -> None\n\
3520Change or add an environment variable.";
3521
Guido van Rossumbcc20741998-08-04 22:53:56 +00003522#ifdef __BEOS__
3523/* We have putenv(), but not in the headers (as of PR2). - [cjh] */
3524int putenv( const char *str );
3525#endif
3526
Fred Drake762e2061999-08-26 17:23:54 +00003527/* Save putenv() parameters as values here, so we can collect them when they
3528 * get re-set with another call for the same key. */
3529static PyObject *posix_putenv_garbage;
3530
Barry Warsaw53699e91996-12-10 23:23:01 +00003531static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003532posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003533{
3534 char *s1, *s2;
3535 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00003536 PyObject *newstr;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003537
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003538 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003539 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003540
3541#if defined(PYOS_OS2)
3542 if (stricmp(s1, "BEGINLIBPATH") == 0) {
3543 APIRET rc;
3544
3545 if (strlen(s2) == 0) /* If New Value is an Empty String */
3546 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3547
3548 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
3549 if (rc != NO_ERROR)
3550 return os2_error(rc);
3551
3552 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
3553 APIRET rc;
3554
3555 if (strlen(s2) == 0) /* If New Value is an Empty String */
3556 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3557
3558 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
3559 if (rc != NO_ERROR)
3560 return os2_error(rc);
3561 } else {
3562#endif
3563
Fred Drake762e2061999-08-26 17:23:54 +00003564 /* XXX This can leak memory -- not easy to fix :-( */
3565 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
3566 if (newstr == NULL)
3567 return PyErr_NoMemory();
3568 new = PyString_AS_STRING(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003569 (void) sprintf(new, "%s=%s", s1, s2);
3570 if (putenv(new)) {
3571 posix_error();
3572 return NULL;
3573 }
Fred Drake762e2061999-08-26 17:23:54 +00003574 /* Install the first arg and newstr in posix_putenv_garbage;
3575 * this will cause previous value to be collected. This has to
3576 * happen after the real putenv() call because the old value
3577 * was still accessible until then. */
3578 if (PyDict_SetItem(posix_putenv_garbage,
3579 PyTuple_GET_ITEM(args, 0), newstr)) {
3580 /* really not much we can do; just leak */
3581 PyErr_Clear();
3582 }
3583 else {
3584 Py_DECREF(newstr);
3585 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003586
3587#if defined(PYOS_OS2)
3588 }
3589#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003590 Py_INCREF(Py_None);
3591 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003592}
Guido van Rossumb6a47161997-09-15 22:54:34 +00003593#endif /* putenv */
3594
3595#ifdef HAVE_STRERROR
3596static char posix_strerror__doc__[] =
3597"strerror(code) -> string\n\
3598Translate an error code to a message string.";
3599
3600PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003601posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00003602{
3603 int code;
3604 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003605 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00003606 return NULL;
3607 message = strerror(code);
3608 if (message == NULL) {
3609 PyErr_SetString(PyExc_ValueError,
3610 "strerror code out of range");
3611 return NULL;
3612 }
3613 return PyString_FromString(message);
3614}
3615#endif /* strerror */
3616
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003617
Guido van Rossumc9641791998-08-04 15:26:23 +00003618#ifdef HAVE_SYS_WAIT_H
3619
3620#ifdef WIFSTOPPED
3621static char posix_WIFSTOPPED__doc__[] =
3622"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003623Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003624
3625static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003626posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003627{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003628#ifdef UNION_WAIT
3629 union wait status;
3630#define status_i (status.w_status)
3631#else
3632 int status;
3633#define status_i status
3634#endif
3635 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003636
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003637 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003638 {
3639 return NULL;
3640 }
3641
3642 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003643#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003644}
3645#endif /* WIFSTOPPED */
3646
3647#ifdef WIFSIGNALED
3648static char posix_WIFSIGNALED__doc__[] =
3649"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00003650Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003651
3652static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003653posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003654{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003655#ifdef UNION_WAIT
3656 union wait status;
3657#define status_i (status.w_status)
3658#else
3659 int status;
3660#define status_i status
3661#endif
3662 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003663
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003664 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003665 {
3666 return NULL;
3667 }
3668
3669 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003670#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003671}
3672#endif /* WIFSIGNALED */
3673
3674#ifdef WIFEXITED
3675static char posix_WIFEXITED__doc__[] =
3676"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003677Return true if the process returning 'status' exited using the exit()\n\
3678system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003679
3680static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003681posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003682{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003683#ifdef UNION_WAIT
3684 union wait status;
3685#define status_i (status.w_status)
3686#else
3687 int status;
3688#define status_i status
3689#endif
3690 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003691
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003692 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003693 {
3694 return NULL;
3695 }
3696
3697 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003698#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003699}
3700#endif /* WIFEXITED */
3701
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003702#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00003703static char posix_WEXITSTATUS__doc__[] =
3704"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003705Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003706
3707static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003708posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003709{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003710#ifdef UNION_WAIT
3711 union wait status;
3712#define status_i (status.w_status)
3713#else
3714 int status;
3715#define status_i status
3716#endif
3717 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003718
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003719 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003720 {
3721 return NULL;
3722 }
3723
3724 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003725#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003726}
3727#endif /* WEXITSTATUS */
3728
3729#ifdef WTERMSIG
3730static char posix_WTERMSIG__doc__[] =
3731"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003732Return the signal that terminated the process that provided the 'status'\n\
3733value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003734
3735static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003736posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003737{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003738#ifdef UNION_WAIT
3739 union wait status;
3740#define status_i (status.w_status)
3741#else
3742 int status;
3743#define status_i status
3744#endif
3745 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003746
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003747 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003748 {
3749 return NULL;
3750 }
3751
3752 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003753#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003754}
3755#endif /* WTERMSIG */
3756
3757#ifdef WSTOPSIG
3758static char posix_WSTOPSIG__doc__[] =
3759"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003760Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003761
3762static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003763posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003764{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003765#ifdef UNION_WAIT
3766 union wait status;
3767#define status_i (status.w_status)
3768#else
3769 int status;
3770#define status_i status
3771#endif
3772 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003773
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003774 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003775 {
3776 return NULL;
3777 }
3778
3779 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003780#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003781}
3782#endif /* WSTOPSIG */
3783
3784#endif /* HAVE_SYS_WAIT_H */
3785
3786
Guido van Rossum94f6f721999-01-06 18:42:14 +00003787#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00003788#ifdef _SCO_DS
3789/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
3790 needed definitions in sys/statvfs.h */
3791#define _SVID3
3792#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003793#include <sys/statvfs.h>
3794
3795static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003796"fstatvfs(fd) -> \n\
3797 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00003798Perform an fstatvfs system call on the given fd.";
3799
3800static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003801posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00003802{
3803 int fd, res;
3804 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003805 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003806 return NULL;
3807 Py_BEGIN_ALLOW_THREADS
3808 res = fstatvfs(fd, &st);
3809 Py_END_ALLOW_THREADS
3810 if (res != 0)
3811 return posix_error();
3812#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003813 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003814 (long) st.f_bsize,
3815 (long) st.f_frsize,
3816 (long) st.f_blocks,
3817 (long) st.f_bfree,
3818 (long) st.f_bavail,
3819 (long) st.f_files,
3820 (long) st.f_ffree,
3821 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003822 (long) st.f_flag,
3823 (long) st.f_namemax);
3824#else
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003825 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003826 (long) st.f_bsize,
3827 (long) st.f_frsize,
3828 (LONG_LONG) st.f_blocks,
3829 (LONG_LONG) st.f_bfree,
3830 (LONG_LONG) st.f_bavail,
3831 (LONG_LONG) st.f_files,
3832 (LONG_LONG) st.f_ffree,
3833 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003834 (long) st.f_flag,
3835 (long) st.f_namemax);
3836#endif
3837}
3838#endif /* HAVE_FSTATVFS */
3839
3840
3841#if defined(HAVE_STATVFS)
3842#include <sys/statvfs.h>
3843
3844static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003845"statvfs(path) -> \n\
3846 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00003847Perform a statvfs system call on the given path.";
3848
3849static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003850posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00003851{
3852 char *path;
3853 int res;
3854 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003855 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003856 return NULL;
3857 Py_BEGIN_ALLOW_THREADS
3858 res = statvfs(path, &st);
3859 Py_END_ALLOW_THREADS
3860 if (res != 0)
3861 return posix_error_with_filename(path);
3862#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003863 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003864 (long) st.f_bsize,
3865 (long) st.f_frsize,
3866 (long) st.f_blocks,
3867 (long) st.f_bfree,
3868 (long) st.f_bavail,
3869 (long) st.f_files,
3870 (long) st.f_ffree,
3871 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003872 (long) st.f_flag,
3873 (long) st.f_namemax);
3874#else /* HAVE_LARGEFILE_SUPPORT */
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003875 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003876 (long) st.f_bsize,
3877 (long) st.f_frsize,
3878 (LONG_LONG) st.f_blocks,
3879 (LONG_LONG) st.f_bfree,
3880 (LONG_LONG) st.f_bavail,
3881 (LONG_LONG) st.f_files,
3882 (LONG_LONG) st.f_ffree,
3883 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003884 (long) st.f_flag,
3885 (long) st.f_namemax);
3886#endif
3887}
3888#endif /* HAVE_STATVFS */
3889
3890
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003891#ifdef HAVE_TEMPNAM
3892static char posix_tempnam__doc__[] = "\
3893tempnam([dir[, prefix]]) -> string\n\
3894Return a unique name for a temporary file.\n\
3895The directory and a short may be specified as strings; they may be omitted\n\
3896or None if not needed.";
3897
3898static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003899posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003900{
3901 PyObject *result = NULL;
3902 char *dir = NULL;
3903 char *pfx = NULL;
3904 char *name;
3905
3906 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
3907 return NULL;
3908 name = tempnam(dir, pfx);
3909 if (name == NULL)
3910 return PyErr_NoMemory();
3911 result = PyString_FromString(name);
3912 free(name);
3913 return result;
3914}
Guido van Rossumd371ff11999-01-25 16:12:23 +00003915#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003916
3917
3918#ifdef HAVE_TMPFILE
3919static char posix_tmpfile__doc__[] = "\
3920tmpfile() -> file object\n\
3921Create a temporary file with no directory entries.";
3922
3923static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003924posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003925{
3926 FILE *fp;
3927
3928 if (!PyArg_ParseTuple(args, ":tmpfile"))
3929 return NULL;
3930 fp = tmpfile();
3931 if (fp == NULL)
3932 return posix_error();
3933 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
3934}
3935#endif
3936
3937
3938#ifdef HAVE_TMPNAM
3939static char posix_tmpnam__doc__[] = "\
3940tmpnam() -> string\n\
3941Return a unique name for a temporary file.";
3942
3943static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003944posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003945{
3946 char buffer[L_tmpnam];
3947 char *name;
3948
3949 if (!PyArg_ParseTuple(args, ":tmpnam"))
3950 return NULL;
Greg Wardb48bc172000-03-01 21:51:56 +00003951#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003952 name = tmpnam_r(buffer);
3953#else
3954 name = tmpnam(buffer);
3955#endif
3956 if (name == NULL) {
3957 PyErr_SetObject(PyExc_OSError,
3958 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00003959#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003960 "unexpected NULL from tmpnam_r"
3961#else
3962 "unexpected NULL from tmpnam"
3963#endif
3964 ));
3965 return NULL;
3966 }
3967 return PyString_FromString(buffer);
3968}
3969#endif
3970
3971
Fred Drakec9680921999-12-13 16:37:25 +00003972/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
3973 * It maps strings representing configuration variable names to
3974 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00003975 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00003976 * rarely-used constants. There are three separate tables that use
3977 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00003978 *
3979 * This code is always included, even if none of the interfaces that
3980 * need it are included. The #if hackery needed to avoid it would be
3981 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00003982 */
3983struct constdef {
3984 char *name;
3985 long value;
3986};
3987
Fred Drake12c6e2d1999-12-14 21:25:03 +00003988static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003989conv_confname(PyObject *arg, int *valuep, struct constdef *table,
3990 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003991{
3992 if (PyInt_Check(arg)) {
3993 *valuep = PyInt_AS_LONG(arg);
3994 return 1;
3995 }
3996 if (PyString_Check(arg)) {
3997 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00003998 size_t lo = 0;
3999 size_t mid;
4000 size_t hi = tablesize;
4001 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004002 char *confname = PyString_AS_STRING(arg);
4003 while (lo < hi) {
4004 mid = (lo + hi) / 2;
4005 cmp = strcmp(confname, table[mid].name);
4006 if (cmp < 0)
4007 hi = mid;
4008 else if (cmp > 0)
4009 lo = mid + 1;
4010 else {
4011 *valuep = table[mid].value;
4012 return 1;
4013 }
4014 }
4015 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
4016 }
4017 else
4018 PyErr_SetString(PyExc_TypeError,
4019 "configuration names must be strings or integers");
4020 return 0;
4021}
4022
4023
4024#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4025static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004026#ifdef _PC_ABI_AIO_XFER_MAX
4027 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
4028#endif
4029#ifdef _PC_ABI_ASYNC_IO
4030 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
4031#endif
Fred Drakec9680921999-12-13 16:37:25 +00004032#ifdef _PC_ASYNC_IO
4033 {"PC_ASYNC_IO", _PC_ASYNC_IO},
4034#endif
4035#ifdef _PC_CHOWN_RESTRICTED
4036 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
4037#endif
4038#ifdef _PC_FILESIZEBITS
4039 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
4040#endif
4041#ifdef _PC_LAST
4042 {"PC_LAST", _PC_LAST},
4043#endif
4044#ifdef _PC_LINK_MAX
4045 {"PC_LINK_MAX", _PC_LINK_MAX},
4046#endif
4047#ifdef _PC_MAX_CANON
4048 {"PC_MAX_CANON", _PC_MAX_CANON},
4049#endif
4050#ifdef _PC_MAX_INPUT
4051 {"PC_MAX_INPUT", _PC_MAX_INPUT},
4052#endif
4053#ifdef _PC_NAME_MAX
4054 {"PC_NAME_MAX", _PC_NAME_MAX},
4055#endif
4056#ifdef _PC_NO_TRUNC
4057 {"PC_NO_TRUNC", _PC_NO_TRUNC},
4058#endif
4059#ifdef _PC_PATH_MAX
4060 {"PC_PATH_MAX", _PC_PATH_MAX},
4061#endif
4062#ifdef _PC_PIPE_BUF
4063 {"PC_PIPE_BUF", _PC_PIPE_BUF},
4064#endif
4065#ifdef _PC_PRIO_IO
4066 {"PC_PRIO_IO", _PC_PRIO_IO},
4067#endif
4068#ifdef _PC_SOCK_MAXBUF
4069 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
4070#endif
4071#ifdef _PC_SYNC_IO
4072 {"PC_SYNC_IO", _PC_SYNC_IO},
4073#endif
4074#ifdef _PC_VDISABLE
4075 {"PC_VDISABLE", _PC_VDISABLE},
4076#endif
4077};
4078
Fred Drakec9680921999-12-13 16:37:25 +00004079static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004080conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004081{
4082 return conv_confname(arg, valuep, posix_constants_pathconf,
4083 sizeof(posix_constants_pathconf)
4084 / sizeof(struct constdef));
4085}
4086#endif
4087
4088#ifdef HAVE_FPATHCONF
4089static char posix_fpathconf__doc__[] = "\
4090fpathconf(fd, name) -> integer\n\
4091Return the configuration limit name for the file descriptor fd.\n\
4092If there is no limit, return -1.";
4093
4094static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004095posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004096{
4097 PyObject *result = NULL;
4098 int name, fd;
4099
Fred Drake12c6e2d1999-12-14 21:25:03 +00004100 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4101 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00004102 long limit;
4103
4104 errno = 0;
4105 limit = fpathconf(fd, name);
4106 if (limit == -1 && errno != 0)
4107 posix_error();
4108 else
4109 result = PyInt_FromLong(limit);
4110 }
4111 return result;
4112}
4113#endif
4114
4115
4116#ifdef HAVE_PATHCONF
4117static char posix_pathconf__doc__[] = "\
4118pathconf(path, name) -> integer\n\
4119Return the configuration limit name for the file or directory path.\n\
4120If there is no limit, return -1.";
4121
4122static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004123posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004124{
4125 PyObject *result = NULL;
4126 int name;
4127 char *path;
4128
4129 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4130 conv_path_confname, &name)) {
4131 long limit;
4132
4133 errno = 0;
4134 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004135 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00004136 if (errno == EINVAL)
4137 /* could be a path or name problem */
4138 posix_error();
4139 else
4140 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004141 }
Fred Drakec9680921999-12-13 16:37:25 +00004142 else
4143 result = PyInt_FromLong(limit);
4144 }
4145 return result;
4146}
4147#endif
4148
4149#ifdef HAVE_CONFSTR
4150static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004151#ifdef _CS_ARCHITECTURE
4152 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4153#endif
4154#ifdef _CS_HOSTNAME
4155 {"CS_HOSTNAME", _CS_HOSTNAME},
4156#endif
4157#ifdef _CS_HW_PROVIDER
4158 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4159#endif
4160#ifdef _CS_HW_SERIAL
4161 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4162#endif
4163#ifdef _CS_INITTAB_NAME
4164 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4165#endif
Fred Drakec9680921999-12-13 16:37:25 +00004166#ifdef _CS_LFS64_CFLAGS
4167 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4168#endif
4169#ifdef _CS_LFS64_LDFLAGS
4170 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4171#endif
4172#ifdef _CS_LFS64_LIBS
4173 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4174#endif
4175#ifdef _CS_LFS64_LINTFLAGS
4176 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4177#endif
4178#ifdef _CS_LFS_CFLAGS
4179 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4180#endif
4181#ifdef _CS_LFS_LDFLAGS
4182 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4183#endif
4184#ifdef _CS_LFS_LIBS
4185 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4186#endif
4187#ifdef _CS_LFS_LINTFLAGS
4188 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4189#endif
Fred Draked86ed291999-12-15 15:34:33 +00004190#ifdef _CS_MACHINE
4191 {"CS_MACHINE", _CS_MACHINE},
4192#endif
Fred Drakec9680921999-12-13 16:37:25 +00004193#ifdef _CS_PATH
4194 {"CS_PATH", _CS_PATH},
4195#endif
Fred Draked86ed291999-12-15 15:34:33 +00004196#ifdef _CS_RELEASE
4197 {"CS_RELEASE", _CS_RELEASE},
4198#endif
4199#ifdef _CS_SRPC_DOMAIN
4200 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4201#endif
4202#ifdef _CS_SYSNAME
4203 {"CS_SYSNAME", _CS_SYSNAME},
4204#endif
4205#ifdef _CS_VERSION
4206 {"CS_VERSION", _CS_VERSION},
4207#endif
Fred Drakec9680921999-12-13 16:37:25 +00004208#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4209 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4210#endif
4211#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4212 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4213#endif
4214#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4215 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4216#endif
4217#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4218 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4219#endif
4220#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4221 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4222#endif
4223#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4224 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4225#endif
4226#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4227 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4228#endif
4229#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4230 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4231#endif
4232#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4233 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4234#endif
4235#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4236 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4237#endif
4238#ifdef _CS_XBS5_LP64_OFF64_LIBS
4239 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4240#endif
4241#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4242 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4243#endif
4244#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4245 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4246#endif
4247#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4248 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4249#endif
4250#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4251 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4252#endif
4253#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4254 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4255#endif
Fred Draked86ed291999-12-15 15:34:33 +00004256#ifdef _MIPS_CS_AVAIL_PROCESSORS
4257 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4258#endif
4259#ifdef _MIPS_CS_BASE
4260 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4261#endif
4262#ifdef _MIPS_CS_HOSTID
4263 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4264#endif
4265#ifdef _MIPS_CS_HW_NAME
4266 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4267#endif
4268#ifdef _MIPS_CS_NUM_PROCESSORS
4269 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4270#endif
4271#ifdef _MIPS_CS_OSREL_MAJ
4272 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4273#endif
4274#ifdef _MIPS_CS_OSREL_MIN
4275 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4276#endif
4277#ifdef _MIPS_CS_OSREL_PATCH
4278 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4279#endif
4280#ifdef _MIPS_CS_OS_NAME
4281 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4282#endif
4283#ifdef _MIPS_CS_OS_PROVIDER
4284 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4285#endif
4286#ifdef _MIPS_CS_PROCESSORS
4287 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4288#endif
4289#ifdef _MIPS_CS_SERIAL
4290 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4291#endif
4292#ifdef _MIPS_CS_VENDOR
4293 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4294#endif
Fred Drakec9680921999-12-13 16:37:25 +00004295};
4296
4297static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004298conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004299{
4300 return conv_confname(arg, valuep, posix_constants_confstr,
4301 sizeof(posix_constants_confstr)
4302 / sizeof(struct constdef));
4303}
4304
4305static char posix_confstr__doc__[] = "\
4306confstr(name) -> string\n\
4307Return a string-valued system configuration variable.";
4308
4309static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004310posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004311{
4312 PyObject *result = NULL;
4313 int name;
4314 char buffer[64];
4315
4316 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4317 int len = confstr(name, buffer, sizeof(buffer));
4318
Fred Drakec9680921999-12-13 16:37:25 +00004319 errno = 0;
4320 if (len == 0) {
4321 if (errno != 0)
4322 posix_error();
4323 else
4324 result = PyString_FromString("");
4325 }
4326 else {
4327 if (len >= sizeof(buffer)) {
4328 result = PyString_FromStringAndSize(NULL, len);
4329 if (result != NULL)
4330 confstr(name, PyString_AS_STRING(result), len+1);
4331 }
4332 else
4333 result = PyString_FromString(buffer);
4334 }
4335 }
4336 return result;
4337}
4338#endif
4339
4340
4341#ifdef HAVE_SYSCONF
4342static struct constdef posix_constants_sysconf[] = {
4343#ifdef _SC_2_CHAR_TERM
4344 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4345#endif
4346#ifdef _SC_2_C_BIND
4347 {"SC_2_C_BIND", _SC_2_C_BIND},
4348#endif
4349#ifdef _SC_2_C_DEV
4350 {"SC_2_C_DEV", _SC_2_C_DEV},
4351#endif
4352#ifdef _SC_2_C_VERSION
4353 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4354#endif
4355#ifdef _SC_2_FORT_DEV
4356 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4357#endif
4358#ifdef _SC_2_FORT_RUN
4359 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4360#endif
4361#ifdef _SC_2_LOCALEDEF
4362 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4363#endif
4364#ifdef _SC_2_SW_DEV
4365 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4366#endif
4367#ifdef _SC_2_UPE
4368 {"SC_2_UPE", _SC_2_UPE},
4369#endif
4370#ifdef _SC_2_VERSION
4371 {"SC_2_VERSION", _SC_2_VERSION},
4372#endif
Fred Draked86ed291999-12-15 15:34:33 +00004373#ifdef _SC_ABI_ASYNCHRONOUS_IO
4374 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4375#endif
4376#ifdef _SC_ACL
4377 {"SC_ACL", _SC_ACL},
4378#endif
Fred Drakec9680921999-12-13 16:37:25 +00004379#ifdef _SC_AIO_LISTIO_MAX
4380 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4381#endif
Fred Drakec9680921999-12-13 16:37:25 +00004382#ifdef _SC_AIO_MAX
4383 {"SC_AIO_MAX", _SC_AIO_MAX},
4384#endif
4385#ifdef _SC_AIO_PRIO_DELTA_MAX
4386 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4387#endif
4388#ifdef _SC_ARG_MAX
4389 {"SC_ARG_MAX", _SC_ARG_MAX},
4390#endif
4391#ifdef _SC_ASYNCHRONOUS_IO
4392 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4393#endif
4394#ifdef _SC_ATEXIT_MAX
4395 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4396#endif
Fred Draked86ed291999-12-15 15:34:33 +00004397#ifdef _SC_AUDIT
4398 {"SC_AUDIT", _SC_AUDIT},
4399#endif
Fred Drakec9680921999-12-13 16:37:25 +00004400#ifdef _SC_AVPHYS_PAGES
4401 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4402#endif
4403#ifdef _SC_BC_BASE_MAX
4404 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4405#endif
4406#ifdef _SC_BC_DIM_MAX
4407 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4408#endif
4409#ifdef _SC_BC_SCALE_MAX
4410 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4411#endif
4412#ifdef _SC_BC_STRING_MAX
4413 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4414#endif
Fred Draked86ed291999-12-15 15:34:33 +00004415#ifdef _SC_CAP
4416 {"SC_CAP", _SC_CAP},
4417#endif
Fred Drakec9680921999-12-13 16:37:25 +00004418#ifdef _SC_CHARCLASS_NAME_MAX
4419 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4420#endif
4421#ifdef _SC_CHAR_BIT
4422 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4423#endif
4424#ifdef _SC_CHAR_MAX
4425 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4426#endif
4427#ifdef _SC_CHAR_MIN
4428 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4429#endif
4430#ifdef _SC_CHILD_MAX
4431 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4432#endif
4433#ifdef _SC_CLK_TCK
4434 {"SC_CLK_TCK", _SC_CLK_TCK},
4435#endif
4436#ifdef _SC_COHER_BLKSZ
4437 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4438#endif
4439#ifdef _SC_COLL_WEIGHTS_MAX
4440 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4441#endif
4442#ifdef _SC_DCACHE_ASSOC
4443 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4444#endif
4445#ifdef _SC_DCACHE_BLKSZ
4446 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4447#endif
4448#ifdef _SC_DCACHE_LINESZ
4449 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4450#endif
4451#ifdef _SC_DCACHE_SZ
4452 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
4453#endif
4454#ifdef _SC_DCACHE_TBLKSZ
4455 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
4456#endif
4457#ifdef _SC_DELAYTIMER_MAX
4458 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
4459#endif
4460#ifdef _SC_EQUIV_CLASS_MAX
4461 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
4462#endif
4463#ifdef _SC_EXPR_NEST_MAX
4464 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
4465#endif
4466#ifdef _SC_FSYNC
4467 {"SC_FSYNC", _SC_FSYNC},
4468#endif
4469#ifdef _SC_GETGR_R_SIZE_MAX
4470 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
4471#endif
4472#ifdef _SC_GETPW_R_SIZE_MAX
4473 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
4474#endif
4475#ifdef _SC_ICACHE_ASSOC
4476 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
4477#endif
4478#ifdef _SC_ICACHE_BLKSZ
4479 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
4480#endif
4481#ifdef _SC_ICACHE_LINESZ
4482 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
4483#endif
4484#ifdef _SC_ICACHE_SZ
4485 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
4486#endif
Fred Draked86ed291999-12-15 15:34:33 +00004487#ifdef _SC_INF
4488 {"SC_INF", _SC_INF},
4489#endif
Fred Drakec9680921999-12-13 16:37:25 +00004490#ifdef _SC_INT_MAX
4491 {"SC_INT_MAX", _SC_INT_MAX},
4492#endif
4493#ifdef _SC_INT_MIN
4494 {"SC_INT_MIN", _SC_INT_MIN},
4495#endif
4496#ifdef _SC_IOV_MAX
4497 {"SC_IOV_MAX", _SC_IOV_MAX},
4498#endif
Fred Draked86ed291999-12-15 15:34:33 +00004499#ifdef _SC_IP_SECOPTS
4500 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
4501#endif
Fred Drakec9680921999-12-13 16:37:25 +00004502#ifdef _SC_JOB_CONTROL
4503 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
4504#endif
Fred Draked86ed291999-12-15 15:34:33 +00004505#ifdef _SC_KERN_POINTERS
4506 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
4507#endif
4508#ifdef _SC_KERN_SIM
4509 {"SC_KERN_SIM", _SC_KERN_SIM},
4510#endif
Fred Drakec9680921999-12-13 16:37:25 +00004511#ifdef _SC_LINE_MAX
4512 {"SC_LINE_MAX", _SC_LINE_MAX},
4513#endif
4514#ifdef _SC_LOGIN_NAME_MAX
4515 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
4516#endif
4517#ifdef _SC_LOGNAME_MAX
4518 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
4519#endif
4520#ifdef _SC_LONG_BIT
4521 {"SC_LONG_BIT", _SC_LONG_BIT},
4522#endif
Fred Draked86ed291999-12-15 15:34:33 +00004523#ifdef _SC_MAC
4524 {"SC_MAC", _SC_MAC},
4525#endif
Fred Drakec9680921999-12-13 16:37:25 +00004526#ifdef _SC_MAPPED_FILES
4527 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
4528#endif
4529#ifdef _SC_MAXPID
4530 {"SC_MAXPID", _SC_MAXPID},
4531#endif
4532#ifdef _SC_MB_LEN_MAX
4533 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
4534#endif
4535#ifdef _SC_MEMLOCK
4536 {"SC_MEMLOCK", _SC_MEMLOCK},
4537#endif
4538#ifdef _SC_MEMLOCK_RANGE
4539 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
4540#endif
4541#ifdef _SC_MEMORY_PROTECTION
4542 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
4543#endif
4544#ifdef _SC_MESSAGE_PASSING
4545 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
4546#endif
Fred Draked86ed291999-12-15 15:34:33 +00004547#ifdef _SC_MMAP_FIXED_ALIGNMENT
4548 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
4549#endif
Fred Drakec9680921999-12-13 16:37:25 +00004550#ifdef _SC_MQ_OPEN_MAX
4551 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
4552#endif
4553#ifdef _SC_MQ_PRIO_MAX
4554 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
4555#endif
Fred Draked86ed291999-12-15 15:34:33 +00004556#ifdef _SC_NACLS_MAX
4557 {"SC_NACLS_MAX", _SC_NACLS_MAX},
4558#endif
Fred Drakec9680921999-12-13 16:37:25 +00004559#ifdef _SC_NGROUPS_MAX
4560 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
4561#endif
4562#ifdef _SC_NL_ARGMAX
4563 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
4564#endif
4565#ifdef _SC_NL_LANGMAX
4566 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
4567#endif
4568#ifdef _SC_NL_MSGMAX
4569 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
4570#endif
4571#ifdef _SC_NL_NMAX
4572 {"SC_NL_NMAX", _SC_NL_NMAX},
4573#endif
4574#ifdef _SC_NL_SETMAX
4575 {"SC_NL_SETMAX", _SC_NL_SETMAX},
4576#endif
4577#ifdef _SC_NL_TEXTMAX
4578 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
4579#endif
4580#ifdef _SC_NPROCESSORS_CONF
4581 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
4582#endif
4583#ifdef _SC_NPROCESSORS_ONLN
4584 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
4585#endif
Fred Draked86ed291999-12-15 15:34:33 +00004586#ifdef _SC_NPROC_CONF
4587 {"SC_NPROC_CONF", _SC_NPROC_CONF},
4588#endif
4589#ifdef _SC_NPROC_ONLN
4590 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
4591#endif
Fred Drakec9680921999-12-13 16:37:25 +00004592#ifdef _SC_NZERO
4593 {"SC_NZERO", _SC_NZERO},
4594#endif
4595#ifdef _SC_OPEN_MAX
4596 {"SC_OPEN_MAX", _SC_OPEN_MAX},
4597#endif
4598#ifdef _SC_PAGESIZE
4599 {"SC_PAGESIZE", _SC_PAGESIZE},
4600#endif
4601#ifdef _SC_PAGE_SIZE
4602 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
4603#endif
4604#ifdef _SC_PASS_MAX
4605 {"SC_PASS_MAX", _SC_PASS_MAX},
4606#endif
4607#ifdef _SC_PHYS_PAGES
4608 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
4609#endif
4610#ifdef _SC_PII
4611 {"SC_PII", _SC_PII},
4612#endif
4613#ifdef _SC_PII_INTERNET
4614 {"SC_PII_INTERNET", _SC_PII_INTERNET},
4615#endif
4616#ifdef _SC_PII_INTERNET_DGRAM
4617 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
4618#endif
4619#ifdef _SC_PII_INTERNET_STREAM
4620 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
4621#endif
4622#ifdef _SC_PII_OSI
4623 {"SC_PII_OSI", _SC_PII_OSI},
4624#endif
4625#ifdef _SC_PII_OSI_CLTS
4626 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
4627#endif
4628#ifdef _SC_PII_OSI_COTS
4629 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
4630#endif
4631#ifdef _SC_PII_OSI_M
4632 {"SC_PII_OSI_M", _SC_PII_OSI_M},
4633#endif
4634#ifdef _SC_PII_SOCKET
4635 {"SC_PII_SOCKET", _SC_PII_SOCKET},
4636#endif
4637#ifdef _SC_PII_XTI
4638 {"SC_PII_XTI", _SC_PII_XTI},
4639#endif
4640#ifdef _SC_POLL
4641 {"SC_POLL", _SC_POLL},
4642#endif
4643#ifdef _SC_PRIORITIZED_IO
4644 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
4645#endif
4646#ifdef _SC_PRIORITY_SCHEDULING
4647 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
4648#endif
4649#ifdef _SC_REALTIME_SIGNALS
4650 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
4651#endif
4652#ifdef _SC_RE_DUP_MAX
4653 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
4654#endif
4655#ifdef _SC_RTSIG_MAX
4656 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
4657#endif
4658#ifdef _SC_SAVED_IDS
4659 {"SC_SAVED_IDS", _SC_SAVED_IDS},
4660#endif
4661#ifdef _SC_SCHAR_MAX
4662 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
4663#endif
4664#ifdef _SC_SCHAR_MIN
4665 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
4666#endif
4667#ifdef _SC_SELECT
4668 {"SC_SELECT", _SC_SELECT},
4669#endif
4670#ifdef _SC_SEMAPHORES
4671 {"SC_SEMAPHORES", _SC_SEMAPHORES},
4672#endif
4673#ifdef _SC_SEM_NSEMS_MAX
4674 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
4675#endif
4676#ifdef _SC_SEM_VALUE_MAX
4677 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
4678#endif
4679#ifdef _SC_SHARED_MEMORY_OBJECTS
4680 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
4681#endif
4682#ifdef _SC_SHRT_MAX
4683 {"SC_SHRT_MAX", _SC_SHRT_MAX},
4684#endif
4685#ifdef _SC_SHRT_MIN
4686 {"SC_SHRT_MIN", _SC_SHRT_MIN},
4687#endif
4688#ifdef _SC_SIGQUEUE_MAX
4689 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
4690#endif
4691#ifdef _SC_SIGRT_MAX
4692 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
4693#endif
4694#ifdef _SC_SIGRT_MIN
4695 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
4696#endif
Fred Draked86ed291999-12-15 15:34:33 +00004697#ifdef _SC_SOFTPOWER
4698 {"SC_SOFTPOWER", _SC_SOFTPOWER},
4699#endif
Fred Drakec9680921999-12-13 16:37:25 +00004700#ifdef _SC_SPLIT_CACHE
4701 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
4702#endif
4703#ifdef _SC_SSIZE_MAX
4704 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
4705#endif
4706#ifdef _SC_STACK_PROT
4707 {"SC_STACK_PROT", _SC_STACK_PROT},
4708#endif
4709#ifdef _SC_STREAM_MAX
4710 {"SC_STREAM_MAX", _SC_STREAM_MAX},
4711#endif
4712#ifdef _SC_SYNCHRONIZED_IO
4713 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
4714#endif
4715#ifdef _SC_THREADS
4716 {"SC_THREADS", _SC_THREADS},
4717#endif
4718#ifdef _SC_THREAD_ATTR_STACKADDR
4719 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
4720#endif
4721#ifdef _SC_THREAD_ATTR_STACKSIZE
4722 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
4723#endif
4724#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
4725 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
4726#endif
4727#ifdef _SC_THREAD_KEYS_MAX
4728 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
4729#endif
4730#ifdef _SC_THREAD_PRIORITY_SCHEDULING
4731 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
4732#endif
4733#ifdef _SC_THREAD_PRIO_INHERIT
4734 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
4735#endif
4736#ifdef _SC_THREAD_PRIO_PROTECT
4737 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
4738#endif
4739#ifdef _SC_THREAD_PROCESS_SHARED
4740 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
4741#endif
4742#ifdef _SC_THREAD_SAFE_FUNCTIONS
4743 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
4744#endif
4745#ifdef _SC_THREAD_STACK_MIN
4746 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
4747#endif
4748#ifdef _SC_THREAD_THREADS_MAX
4749 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
4750#endif
4751#ifdef _SC_TIMERS
4752 {"SC_TIMERS", _SC_TIMERS},
4753#endif
4754#ifdef _SC_TIMER_MAX
4755 {"SC_TIMER_MAX", _SC_TIMER_MAX},
4756#endif
4757#ifdef _SC_TTY_NAME_MAX
4758 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
4759#endif
4760#ifdef _SC_TZNAME_MAX
4761 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
4762#endif
4763#ifdef _SC_T_IOV_MAX
4764 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
4765#endif
4766#ifdef _SC_UCHAR_MAX
4767 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
4768#endif
4769#ifdef _SC_UINT_MAX
4770 {"SC_UINT_MAX", _SC_UINT_MAX},
4771#endif
4772#ifdef _SC_UIO_MAXIOV
4773 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
4774#endif
4775#ifdef _SC_ULONG_MAX
4776 {"SC_ULONG_MAX", _SC_ULONG_MAX},
4777#endif
4778#ifdef _SC_USHRT_MAX
4779 {"SC_USHRT_MAX", _SC_USHRT_MAX},
4780#endif
4781#ifdef _SC_VERSION
4782 {"SC_VERSION", _SC_VERSION},
4783#endif
4784#ifdef _SC_WORD_BIT
4785 {"SC_WORD_BIT", _SC_WORD_BIT},
4786#endif
4787#ifdef _SC_XBS5_ILP32_OFF32
4788 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
4789#endif
4790#ifdef _SC_XBS5_ILP32_OFFBIG
4791 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
4792#endif
4793#ifdef _SC_XBS5_LP64_OFF64
4794 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
4795#endif
4796#ifdef _SC_XBS5_LPBIG_OFFBIG
4797 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
4798#endif
4799#ifdef _SC_XOPEN_CRYPT
4800 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
4801#endif
4802#ifdef _SC_XOPEN_ENH_I18N
4803 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
4804#endif
4805#ifdef _SC_XOPEN_LEGACY
4806 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
4807#endif
4808#ifdef _SC_XOPEN_REALTIME
4809 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
4810#endif
4811#ifdef _SC_XOPEN_REALTIME_THREADS
4812 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
4813#endif
4814#ifdef _SC_XOPEN_SHM
4815 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
4816#endif
4817#ifdef _SC_XOPEN_UNIX
4818 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
4819#endif
4820#ifdef _SC_XOPEN_VERSION
4821 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
4822#endif
4823#ifdef _SC_XOPEN_XCU_VERSION
4824 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
4825#endif
4826#ifdef _SC_XOPEN_XPG2
4827 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
4828#endif
4829#ifdef _SC_XOPEN_XPG3
4830 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
4831#endif
4832#ifdef _SC_XOPEN_XPG4
4833 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
4834#endif
4835};
4836
4837static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004838conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004839{
4840 return conv_confname(arg, valuep, posix_constants_sysconf,
4841 sizeof(posix_constants_sysconf)
4842 / sizeof(struct constdef));
4843}
4844
4845static char posix_sysconf__doc__[] = "\
4846sysconf(name) -> integer\n\
4847Return an integer-valued system configuration variable.";
4848
4849static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004850posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004851{
4852 PyObject *result = NULL;
4853 int name;
4854
4855 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
4856 int value;
4857
4858 errno = 0;
4859 value = sysconf(name);
4860 if (value == -1 && errno != 0)
4861 posix_error();
4862 else
4863 result = PyInt_FromLong(value);
4864 }
4865 return result;
4866}
4867#endif
4868
4869
Fred Drakebec628d1999-12-15 18:31:10 +00004870/* This code is used to ensure that the tables of configuration value names
4871 * are in sorted order as required by conv_confname(), and also to build the
4872 * the exported dictionaries that are used to publish information about the
4873 * names available on the host platform.
4874 *
4875 * Sorting the table at runtime ensures that the table is properly ordered
4876 * when used, even for platforms we're not able to test on. It also makes
4877 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00004878 */
Fred Drakebec628d1999-12-15 18:31:10 +00004879
4880static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004881cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00004882{
4883 const struct constdef *c1 =
4884 (const struct constdef *) v1;
4885 const struct constdef *c2 =
4886 (const struct constdef *) v2;
4887
4888 return strcmp(c1->name, c2->name);
4889}
4890
4891static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004892setup_confname_table(struct constdef *table, size_t tablesize,
4893 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00004894{
Fred Drakebec628d1999-12-15 18:31:10 +00004895 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00004896 size_t i;
4897 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00004898
4899 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
4900 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00004901 if (d == NULL)
4902 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004903
Barry Warsaw3155db32000-04-13 15:20:40 +00004904 for (i=0; i < tablesize; ++i) {
4905 PyObject *o = PyInt_FromLong(table[i].value);
4906 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
4907 Py_XDECREF(o);
4908 Py_DECREF(d);
4909 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004910 }
Barry Warsaw3155db32000-04-13 15:20:40 +00004911 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00004912 }
Barry Warsaw3155db32000-04-13 15:20:40 +00004913 status = PyDict_SetItemString(moddict, tablename, d);
4914 Py_DECREF(d);
4915 return status;
Fred Draked86ed291999-12-15 15:34:33 +00004916}
4917
Fred Drakebec628d1999-12-15 18:31:10 +00004918/* Return -1 on failure, 0 on success. */
4919static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004920setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00004921{
4922#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00004923 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00004924 sizeof(posix_constants_pathconf)
4925 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00004926 "pathconf_names", moddict))
4927 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004928#endif
4929#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00004930 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00004931 sizeof(posix_constants_confstr)
4932 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00004933 "confstr_names", moddict))
4934 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004935#endif
4936#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00004937 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00004938 sizeof(posix_constants_sysconf)
4939 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00004940 "sysconf_names", moddict))
4941 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004942#endif
Fred Drakebec628d1999-12-15 18:31:10 +00004943 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00004944}
Fred Draked86ed291999-12-15 15:34:33 +00004945
4946
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004947static char posix_abort__doc__[] = "\
4948abort() -> does not return!\n\
4949Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
4950in the hardest way possible on the hosting operating system.";
4951
4952static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004953posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004954{
4955 if (!PyArg_ParseTuple(args, ":abort"))
4956 return NULL;
4957 abort();
4958 /*NOTREACHED*/
4959 Py_FatalError("abort() called from Python code didn't abort!");
4960 return NULL;
4961}
Fred Drakebec628d1999-12-15 18:31:10 +00004962
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004963
4964static PyMethodDef posix_methods[] = {
4965 {"access", posix_access, METH_VARARGS, posix_access__doc__},
4966#ifdef HAVE_TTYNAME
4967 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
4968#endif
4969 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
4970 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004971#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004972 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004973#endif /* HAVE_CHOWN */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004974#ifdef HAVE_CTERMID
4975 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
4976#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00004977#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004978 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00004979#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004980#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004981 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004982#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004983 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
4984 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
4985 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004986#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004987 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004988#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004989#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004990 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004991#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004992 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
4993 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
4994 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004995#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004996 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004997#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004998#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004999 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005000#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005001 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005002#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005003 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005004#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005005 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
5006 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
5007 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005008#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005009 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005010#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005011 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005012#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005013 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5014 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005015#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00005016#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005017 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5018 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00005019#endif /* HAVE_SPAWNV */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005020#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005021 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005022#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005023#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005024 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00005025#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005026#ifdef HAVE_FORKPTY
5027 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5028#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005029#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005030 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005031#endif /* HAVE_GETEGID */
5032#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005033 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005034#endif /* HAVE_GETEUID */
5035#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005036 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005037#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00005038#ifdef HAVE_GETGROUPS
5039 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5040#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005041 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005042#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005043 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005044#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005045#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005046 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005047#endif /* HAVE_GETPPID */
5048#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005049 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005050#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005051#ifdef HAVE_GETLOGIN
5052 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5053#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00005054#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005055 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005056#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00005057#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005058 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00005059#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005060#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005061 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005062#ifdef MS_WIN32
5063 {"popen2", win32_popen2, METH_VARARGS},
5064 {"popen3", win32_popen3, METH_VARARGS},
5065 {"popen4", win32_popen4, METH_VARARGS},
5066#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005067#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005068#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005069 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005070#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005071#ifdef HAVE_SETEUID
5072 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5073#endif /* HAVE_SETEUID */
5074#ifdef HAVE_SETEGID
5075 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5076#endif /* HAVE_SETEGID */
5077#ifdef HAVE_SETREUID
5078 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5079#endif /* HAVE_SETREUID */
5080#ifdef HAVE_SETREGID
5081 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5082#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005083#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005084 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005085#endif /* HAVE_SETGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005086#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005087 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005088#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005089#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005090 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005091#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005092#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005093 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005094#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005095#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005096 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005097#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005098#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005099 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005100#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005101#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005102 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005103#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005104#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005105 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005106#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005107 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5108 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5109 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5110 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5111 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5112 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5113 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5114 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5115 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00005116 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005117#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005118 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005119#endif
5120#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005121 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005122#endif
5123#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005124 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005125#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005126#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005127 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005128#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00005129#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005130 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00005131#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00005132#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005133 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005134#endif
5135#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005136 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005137#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00005138#ifdef HAVE_SYS_WAIT_H
5139#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005140 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005141#endif /* WIFSTOPPED */
5142#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005143 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005144#endif /* WIFSIGNALED */
5145#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005146 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005147#endif /* WIFEXITED */
5148#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005149 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005150#endif /* WEXITSTATUS */
5151#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005152 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005153#endif /* WTERMSIG */
5154#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005155 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005156#endif /* WSTOPSIG */
5157#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005158#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005159 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005160#endif
5161#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005162 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005163#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005164#ifdef HAVE_TMPNAM
5165 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5166#endif
5167#ifdef HAVE_TEMPNAM
5168 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5169#endif
5170#ifdef HAVE_TMPNAM
5171 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5172#endif
Fred Drakec9680921999-12-13 16:37:25 +00005173#ifdef HAVE_CONFSTR
5174 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5175#endif
5176#ifdef HAVE_SYSCONF
5177 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5178#endif
5179#ifdef HAVE_FPATHCONF
5180 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5181#endif
5182#ifdef HAVE_PATHCONF
5183 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5184#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005185 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005186 {NULL, NULL} /* Sentinel */
5187};
5188
5189
Barry Warsaw4a342091996-12-19 23:50:02 +00005190static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005191ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005192{
5193 PyObject* v = PyInt_FromLong(value);
5194 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5195 return -1; /* triggers fatal error */
5196
5197 Py_DECREF(v);
5198 return 0;
5199}
5200
Guido van Rossumd48f2521997-12-05 22:19:34 +00005201#if defined(PYOS_OS2)
5202/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5203static int insertvalues(PyObject *d)
5204{
5205 APIRET rc;
5206 ULONG values[QSV_MAX+1];
5207 PyObject *v;
5208 char *ver, tmp[10];
5209
5210 Py_BEGIN_ALLOW_THREADS
5211 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5212 Py_END_ALLOW_THREADS
5213
5214 if (rc != NO_ERROR) {
5215 os2_error(rc);
5216 return -1;
5217 }
5218
5219 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5220 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5221 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5222 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5223 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5224 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5225 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5226
5227 switch (values[QSV_VERSION_MINOR]) {
5228 case 0: ver = "2.00"; break;
5229 case 10: ver = "2.10"; break;
5230 case 11: ver = "2.11"; break;
5231 case 30: ver = "3.00"; break;
5232 case 40: ver = "4.00"; break;
5233 case 50: ver = "5.00"; break;
5234 default:
5235 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
5236 values[QSV_VERSION_MINOR]);
5237 ver = &tmp[0];
5238 }
5239
5240 /* Add Indicator of the Version of the Operating System */
5241 v = PyString_FromString(ver);
5242 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5243 return -1;
5244 Py_DECREF(v);
5245
5246 /* Add Indicator of Which Drive was Used to Boot the System */
5247 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5248 tmp[1] = ':';
5249 tmp[2] = '\0';
5250
5251 v = PyString_FromString(tmp);
5252 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5253 return -1;
5254 Py_DECREF(v);
5255
5256 return 0;
5257}
5258#endif
5259
Barry Warsaw4a342091996-12-19 23:50:02 +00005260static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005261all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00005262{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005263#ifdef F_OK
5264 if (ins(d, "F_OK", (long)F_OK)) return -1;
5265#endif
5266#ifdef R_OK
5267 if (ins(d, "R_OK", (long)R_OK)) return -1;
5268#endif
5269#ifdef W_OK
5270 if (ins(d, "W_OK", (long)W_OK)) return -1;
5271#endif
5272#ifdef X_OK
5273 if (ins(d, "X_OK", (long)X_OK)) return -1;
5274#endif
Fred Drakec9680921999-12-13 16:37:25 +00005275#ifdef NGROUPS_MAX
5276 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5277#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005278#ifdef TMP_MAX
5279 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5280#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005281#ifdef WNOHANG
5282 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5283#endif
5284#ifdef O_RDONLY
5285 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5286#endif
5287#ifdef O_WRONLY
5288 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5289#endif
5290#ifdef O_RDWR
5291 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5292#endif
5293#ifdef O_NDELAY
5294 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5295#endif
5296#ifdef O_NONBLOCK
5297 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5298#endif
5299#ifdef O_APPEND
5300 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5301#endif
5302#ifdef O_DSYNC
5303 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5304#endif
5305#ifdef O_RSYNC
5306 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5307#endif
5308#ifdef O_SYNC
5309 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5310#endif
5311#ifdef O_NOCTTY
5312 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5313#endif
5314#ifdef O_CREAT
5315 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5316#endif
5317#ifdef O_EXCL
5318 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5319#endif
5320#ifdef O_TRUNC
5321 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5322#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005323#ifdef O_BINARY
5324 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5325#endif
5326#ifdef O_TEXT
5327 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5328#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005329
Guido van Rossum246bc171999-02-01 23:54:31 +00005330#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005331 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5332 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5333 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5334 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5335 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005336#endif
5337
Guido van Rossumd48f2521997-12-05 22:19:34 +00005338#if defined(PYOS_OS2)
5339 if (insertvalues(d)) return -1;
5340#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005341 return 0;
5342}
5343
5344
Guido van Rossumc5a0f531997-12-02 20:36:02 +00005345#if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005346#define INITFUNC initnt
5347#define MODNAME "nt"
5348#else
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005349#if defined(PYOS_OS2)
5350#define INITFUNC initos2
5351#define MODNAME "os2"
5352#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005353#define INITFUNC initposix
5354#define MODNAME "posix"
5355#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005356#endif
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005357
Guido van Rossum3886bb61998-12-04 18:50:17 +00005358DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005359INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00005360{
Barry Warsaw53699e91996-12-10 23:23:01 +00005361 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005362
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005363 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005364 posix_methods,
5365 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005366 (PyObject *)NULL,
5367 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005368 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005369
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005370 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005371 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005372 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005373 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005374 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005375
Barry Warsaw4a342091996-12-19 23:50:02 +00005376 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005377 return;
5378
Fred Drakebec628d1999-12-15 18:31:10 +00005379 if (setup_confname_tables(d))
5380 return;
5381
Barry Warsawca74da41999-02-09 19:31:45 +00005382 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005383
Guido van Rossumb3d39562000-01-31 18:41:26 +00005384#ifdef HAVE_PUTENV
Fred Drake762e2061999-08-26 17:23:54 +00005385 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00005386#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005387}