blob: e3461245e8dc3559b8518b25ea4fc5b85288d6f9 [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#ifdef HAVE_FCNTL_H
49#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000050#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000051
Guido van Rossuma4916fa1996-05-23 22:58:55 +000052/* Various compilers have only certain posix functions */
Guido van Rossum6d8841c1997-08-14 19:57:39 +000053/* XXX Gosh I wish these were all moved into config.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000054#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000055#include <process.h>
56#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000057#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000058#define HAVE_GETCWD 1
59#define HAVE_OPENDIR 1
60#define HAVE_SYSTEM 1
61#if defined(__OS2__)
62#define HAVE_EXECV 1
63#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000064#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000065#include <process.h>
66#else
67#ifdef __BORLANDC__ /* Borland compiler */
68#define HAVE_EXECV 1
69#define HAVE_GETCWD 1
70#define HAVE_GETEGID 1
71#define HAVE_GETEUID 1
72#define HAVE_GETGID 1
73#define HAVE_GETPPID 1
74#define HAVE_GETUID 1
75#define HAVE_KILL 1
76#define HAVE_OPENDIR 1
77#define HAVE_PIPE 1
78#define HAVE_POPEN 1
79#define HAVE_SYSTEM 1
80#define HAVE_WAIT 1
81#else
82#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000083#define HAVE_GETCWD 1
84#ifdef MS_WIN32
Guido van Rossuma1065681999-01-25 23:20:23 +000085#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000086#define HAVE_EXECV 1
87#define HAVE_PIPE 1
88#define HAVE_POPEN 1
89#define HAVE_SYSTEM 1
90#else /* 16-bit Windows */
Guido van Rossum8d665e61996-06-26 18:22:49 +000091#endif /* !MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000092#else /* all other compilers */
93/* Unix functions that the configure script doesn't check for */
94#define HAVE_EXECV 1
95#define HAVE_FORK 1
96#define HAVE_GETCWD 1
97#define HAVE_GETEGID 1
98#define HAVE_GETEUID 1
99#define HAVE_GETGID 1
100#define HAVE_GETPPID 1
101#define HAVE_GETUID 1
102#define HAVE_KILL 1
103#define HAVE_OPENDIR 1
104#define HAVE_PIPE 1
105#define HAVE_POPEN 1
106#define HAVE_SYSTEM 1
107#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000108#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000109#endif /* _MSC_VER */
110#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000111#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000112#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000113
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000114#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000115
Guido van Rossumb6775db1994-08-01 11:34:53 +0000116#ifdef HAVE_UNISTD_H
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000117#include <unistd.h>
Guido van Rossum36bc6801995-06-14 22:54:23 +0000118#endif
119
120#ifdef NeXT
121/* NeXT's <unistd.h> and <utime.h> aren't worth much */
122#undef HAVE_UNISTD_H
123#undef HAVE_UTIME_H
Guido van Rossumb9f866c1997-05-22 15:12:39 +0000124#define HAVE_WAITPID
Guido van Rossum36bc6801995-06-14 22:54:23 +0000125/* #undef HAVE_GETCWD */
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000126#define UNION_WAIT /* This should really be checked for by autoconf */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000127#endif
128
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000129#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000130#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000131extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000132#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000133#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000134extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000135#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000136extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000137#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000138#endif
139#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000140extern int chdir(char *);
141extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000142#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000143extern int chdir(const char *);
144extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000145#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000146extern int chmod(const char *, mode_t);
147extern int chown(const char *, uid_t, gid_t);
148extern char *getcwd(char *, int);
149extern char *strerror(int);
150extern int link(const char *, const char *);
151extern int rename(const char *, const char *);
152extern int stat(const char *, struct stat *);
153extern int unlink(const char *);
154extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000155#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000156extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000157#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000158#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000159extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000160#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000161#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000162
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000163#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000164
Guido van Rossumb6775db1994-08-01 11:34:53 +0000165#ifdef HAVE_UTIME_H
166#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000167#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000168
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000169#ifdef HAVE_SYS_UTIME_H
170#include <sys/utime.h>
171#define HAVE_UTIME_H /* pretend we do for the rest of this file */
172#endif /* HAVE_SYS_UTIME_H */
173
Guido van Rossumb6775db1994-08-01 11:34:53 +0000174#ifdef HAVE_SYS_TIMES_H
175#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000176#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000177
178#ifdef HAVE_SYS_PARAM_H
179#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000180#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000181
182#ifdef HAVE_SYS_UTSNAME_H
183#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000184#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000185
186#ifndef MAXPATHLEN
187#define MAXPATHLEN 1024
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000188#endif /* MAXPATHLEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000189
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000190#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000191#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000192#define NAMLEN(dirent) strlen((dirent)->d_name)
193#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000194#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000195#include <direct.h>
196#define NAMLEN(dirent) strlen((dirent)->d_name)
197#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000198#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000199#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000200#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000201#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000202#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000203#endif
204#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000206#endif
207#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000209#endif
210#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000212#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000213#include <direct.h>
214#include <io.h>
215#include <process.h>
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000216#define WINDOWS_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217#include <windows.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000218#ifdef MS_WIN32
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000219#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000220#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000221#else /* 16-bit Windows */
222#include <dos.h>
223#include <ctype.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000224#endif /* MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000225#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226
Guido van Rossumd48f2521997-12-05 22:19:34 +0000227#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000228#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000229#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000230
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000231#ifdef UNION_WAIT
232/* Emulate some macros on systems that have a union instead of macros */
233
234#ifndef WIFEXITED
235#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
236#endif
237
238#ifndef WEXITSTATUS
239#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
240#endif
241
242#ifndef WTERMSIG
243#define WTERMSIG(u_wait) ((u_wait).w_termsig)
244#endif
245
246#endif /* UNION_WAIT */
247
Greg Wardb48bc172000-03-01 21:51:56 +0000248/* Don't use the "_r" form if we don't need it (also, won't have a
249 prototype for it, at least on Solaris -- maybe others as well?). */
250#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
251#define USE_CTERMID_R
252#endif
253
254#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
255#define USE_TMPNAM_R
256#endif
257
Fred Drake699f3522000-06-29 21:12:41 +0000258/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000259#undef STAT
Fred Drake699f3522000-06-29 21:12:41 +0000260#ifdef MS_WIN64
261# define STAT _stati64
262# define FSTAT _fstati64
263# define STRUCT_STAT struct _stati64
264#else
265# define STAT stat
266# define FSTAT fstat
267# define STRUCT_STAT struct stat
268#endif
269
270
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000271/* Return a dictionary corresponding to the POSIX environment table */
272
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000273#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000274extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000275#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000276
Barry Warsaw53699e91996-12-10 23:23:01 +0000277static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000278convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000279{
Barry Warsaw53699e91996-12-10 23:23:01 +0000280 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000281 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000282 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000283 if (d == NULL)
284 return NULL;
285 if (environ == NULL)
286 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000287 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000288 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000289 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000290 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000291 char *p = strchr(*e, '=');
292 if (p == NULL)
293 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000294 k = PyString_FromStringAndSize(*e, (int)(p-*e));
295 if (k == NULL) {
296 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000297 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000298 }
299 v = PyString_FromString(p+1);
300 if (v == NULL) {
301 PyErr_Clear();
302 Py_DECREF(k);
303 continue;
304 }
305 if (PyDict_GetItem(d, k) == NULL) {
306 if (PyDict_SetItem(d, k, v) != 0)
307 PyErr_Clear();
308 }
309 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000310 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000311 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000312#if defined(PYOS_OS2)
313 {
314 APIRET rc;
315 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
316
317 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000318 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000319 PyObject *v = PyString_FromString(buffer);
320 PyDict_SetItemString(d, "BEGINLIBPATH", v);
321 Py_DECREF(v);
322 }
323 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
324 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
325 PyObject *v = PyString_FromString(buffer);
326 PyDict_SetItemString(d, "ENDLIBPATH", v);
327 Py_DECREF(v);
328 }
329 }
330#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000331 return d;
332}
333
334
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000335/* Set a POSIX-specific error from errno, and return NULL */
336
Barry Warsawd58d7641998-07-23 16:14:40 +0000337static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000338posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000339{
Barry Warsawca74da41999-02-09 19:31:45 +0000340 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000341}
Barry Warsawd58d7641998-07-23 16:14:40 +0000342static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000343posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000344{
Barry Warsawca74da41999-02-09 19:31:45 +0000345 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000346}
347
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000348#ifdef MS_WIN32
349static PyObject *
350win32_error(char* function, char* filename)
351{
352 /* XXX this could be improved */
353 errno = GetLastError();
354 if (filename)
355 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename);
356 else
357 return PyErr_SetFromErrno(PyExc_OSError);
358}
359#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000360
Guido van Rossumd48f2521997-12-05 22:19:34 +0000361#if defined(PYOS_OS2)
362/**********************************************************************
363 * Helper Function to Trim and Format OS/2 Messages
364 **********************************************************************/
365 static void
366os2_formatmsg(char *msgbuf, int msglen, char *reason)
367{
368 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
369
370 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
371 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
372
373 while (lastc > msgbuf && isspace(*lastc))
374 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
375 }
376
377 /* Add Optional Reason Text */
378 if (reason) {
379 strcat(msgbuf, " : ");
380 strcat(msgbuf, reason);
381 }
382}
383
384/**********************************************************************
385 * Decode an OS/2 Operating System Error Code
386 *
387 * A convenience function to lookup an OS/2 error code and return a
388 * text message we can use to raise a Python exception.
389 *
390 * Notes:
391 * The messages for errors returned from the OS/2 kernel reside in
392 * the file OSO001.MSG in the \OS2 directory hierarchy.
393 *
394 **********************************************************************/
395 static char *
396os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
397{
398 APIRET rc;
399 ULONG msglen;
400
401 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
402 Py_BEGIN_ALLOW_THREADS
403 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
404 errorcode, "oso001.msg", &msglen);
405 Py_END_ALLOW_THREADS
406
407 if (rc == NO_ERROR)
408 os2_formatmsg(msgbuf, msglen, reason);
409 else
410 sprintf(msgbuf, "unknown OS error #%d", errorcode);
411
412 return msgbuf;
413}
414
415/* Set an OS/2-specific error and return NULL. OS/2 kernel
416 errors are not in a global variable e.g. 'errno' nor are
417 they congruent with posix error numbers. */
418
419static PyObject * os2_error(int code)
420{
421 char text[1024];
422 PyObject *v;
423
424 os2_strerror(text, sizeof(text), code, "");
425
426 v = Py_BuildValue("(is)", code, text);
427 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000428 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000429 Py_DECREF(v);
430 }
431 return NULL; /* Signal to Python that an Exception is Pending */
432}
433
434#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000435
436/* POSIX generic methods */
437
Barry Warsaw53699e91996-12-10 23:23:01 +0000438static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000439posix_int(PyObject *args, char *format, int (*func)(int))
Guido van Rossum21142a01999-01-08 21:05:37 +0000440{
441 int fd;
442 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000443 if (!PyArg_ParseTuple(args, format, &fd))
Guido van Rossum21142a01999-01-08 21:05:37 +0000444 return NULL;
445 Py_BEGIN_ALLOW_THREADS
446 res = (*func)(fd);
447 Py_END_ALLOW_THREADS
448 if (res < 0)
449 return posix_error();
450 Py_INCREF(Py_None);
451 return Py_None;
452}
453
454
455static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000456posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000457{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000458 char *path1;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000459 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000460 if (!PyArg_ParseTuple(args, format, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000461 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000462 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000463 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000464 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000465 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000466 return posix_error_with_filename(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000467 Py_INCREF(Py_None);
468 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000469}
470
Barry Warsaw53699e91996-12-10 23:23:01 +0000471static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000472posix_2str(PyObject *args, char *format,
473 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000474{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000475 char *path1, *path2;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000476 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000477 if (!PyArg_ParseTuple(args, format, &path1, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000478 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000479 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000480 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000481 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000482 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000483 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000484 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000485 Py_INCREF(Py_None);
486 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000487}
488
Fred Drake699f3522000-06-29 21:12:41 +0000489/* pack a system stat C structure into the Python stat tuple
490 (used by posix_stat() and posix_fstat()) */
491static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000492_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000493{
494 PyObject *v = PyTuple_New(10);
495 if (v == NULL)
496 return NULL;
497
498 PyTuple_SetItem(v, 0, PyInt_FromLong((long)st.st_mode));
499#ifdef HAVE_LARGEFILE_SUPPORT
500 PyTuple_SetItem(v, 1, PyLong_FromLongLong((LONG_LONG)st.st_ino));
501#else
502 PyTuple_SetItem(v, 1, PyInt_FromLong((long)st.st_ino));
503#endif
504#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
505 PyTuple_SetItem(v, 2, PyLong_FromLongLong((LONG_LONG)st.st_dev));
506#else
507 PyTuple_SetItem(v, 2, PyInt_FromLong((long)st.st_dev));
508#endif
509 PyTuple_SetItem(v, 3, PyInt_FromLong((long)st.st_nlink));
510 PyTuple_SetItem(v, 4, PyInt_FromLong((long)st.st_uid));
511 PyTuple_SetItem(v, 5, PyInt_FromLong((long)st.st_gid));
512#ifdef HAVE_LARGEFILE_SUPPORT
513 PyTuple_SetItem(v, 6, PyLong_FromLongLong((LONG_LONG)st.st_size));
514#else
515 PyTuple_SetItem(v, 6, PyInt_FromLong(st.st_size));
516#endif
517#if SIZEOF_TIME_T > SIZEOF_LONG
518 PyTuple_SetItem(v, 7, PyLong_FromLongLong((LONG_LONG)st.st_atime));
519 PyTuple_SetItem(v, 8, PyLong_FromLongLong((LONG_LONG)st.st_mtime));
520 PyTuple_SetItem(v, 9, PyLong_FromLongLong((LONG_LONG)st.st_ctime));
521#else
522 PyTuple_SetItem(v, 7, PyInt_FromLong((long)st.st_atime));
523 PyTuple_SetItem(v, 8, PyInt_FromLong((long)st.st_mtime));
524 PyTuple_SetItem(v, 9, PyInt_FromLong((long)st.st_ctime));
525#endif
526
527 if (PyErr_Occurred()) {
528 Py_DECREF(v);
529 return NULL;
530 }
531
532 return v;
533}
534
535
Barry Warsaw53699e91996-12-10 23:23:01 +0000536static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000537posix_do_stat(PyObject *self, PyObject *args, char *format,
538 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000539{
Fred Drake699f3522000-06-29 21:12:41 +0000540 STRUCT_STAT st;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000541 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000542 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000543
544#ifdef MS_WIN32
545 int pathlen;
546 char pathcopy[MAX_PATH];
547#endif /* MS_WIN32 */
548
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000549 if (!PyArg_ParseTuple(args, format, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000550 return NULL;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000551
552#ifdef MS_WIN32
553 pathlen = strlen(path);
554 /* the library call can blow up if the file name is too long! */
555 if (pathlen > MAX_PATH) {
556 errno = ENAMETOOLONG;
557 return posix_error();
558 }
559
560 if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) {
Guido van Rossum19dde102000-05-03 02:44:55 +0000561 /* exception for specific or current drive root */
562 if (!((pathlen == 1) ||
563 ((pathlen == 3) &&
Guido van Rossumace88ae2000-04-21 18:54:45 +0000564 (path[1] == ':') &&
Guido van Rossum19dde102000-05-03 02:44:55 +0000565 (path[2] == '\\' || path[2] == '/'))))
Guido van Rossumace88ae2000-04-21 18:54:45 +0000566 {
567 strncpy(pathcopy, path, pathlen);
568 pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */
569 path = pathcopy;
570 }
571 }
572#endif /* MS_WIN32 */
573
Barry Warsaw53699e91996-12-10 23:23:01 +0000574 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000575 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000576 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000577 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000578 return posix_error_with_filename(path);
Fred Drake699f3522000-06-29 21:12:41 +0000579
580 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000581}
582
583
584/* POSIX methods */
585
Guido van Rossum94f6f721999-01-06 18:42:14 +0000586static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000587"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000588Test for access to a file.";
589
590static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000591posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000592{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000593 char *path;
594 int mode;
595 int res;
596
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000597 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000598 return NULL;
599 Py_BEGIN_ALLOW_THREADS
600 res = access(path, mode);
601 Py_END_ALLOW_THREADS
602 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000603}
604
Guido van Rossumd371ff11999-01-25 16:12:23 +0000605#ifndef F_OK
606#define F_OK 0
607#endif
608#ifndef R_OK
609#define R_OK 4
610#endif
611#ifndef W_OK
612#define W_OK 2
613#endif
614#ifndef X_OK
615#define X_OK 1
616#endif
617
618#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000619static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000620"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000621Return the name of the terminal device connected to 'fd'.";
622
623static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000624posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000625{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000626 int id;
627 char *ret;
628
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000629 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000630 return NULL;
631
Guido van Rossum94f6f721999-01-06 18:42:14 +0000632 ret = ttyname(id);
633 if (ret == NULL)
634 return(posix_error());
635 return(PyString_FromString(ret));
636}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000637#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000638
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000639#ifdef HAVE_CTERMID
640static char posix_ctermid__doc__[] =
641"ctermid() -> String\n\
642Return the name of the controlling terminal for this process.";
643
644static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000645posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000646{
647 char *ret;
648 char buffer[L_ctermid];
649
650 if (!PyArg_ParseTuple(args, ":ctermid"))
651 return NULL;
652
Greg Wardb48bc172000-03-01 21:51:56 +0000653#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000654 ret = ctermid_r(buffer);
655#else
656 ret = ctermid(buffer);
657#endif
658 if (ret == NULL)
659 return(posix_error());
660 return(PyString_FromString(buffer));
661}
662#endif
663
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000664static char posix_chdir__doc__[] =
665"chdir(path) -> None\n\
666Change the current working directory to the specified path.";
667
Barry Warsaw53699e91996-12-10 23:23:01 +0000668static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000669posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000670{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000671 return posix_1str(args, "s:chdir", chdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000672}
673
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000674
675static char posix_chmod__doc__[] =
676"chmod(path, mode) -> None\n\
677Change the access permissions of a file.";
678
Barry Warsaw53699e91996-12-10 23:23:01 +0000679static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000680posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000681{
Guido van Rossumffd15f52000-03-31 00:47:28 +0000682 char *path;
683 int i;
684 int res;
Guido van Rossum49679b42000-03-31 00:48:21 +0000685 if (!PyArg_ParseTuple(args, "si", &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000686 return NULL;
687 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000688 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000689 Py_END_ALLOW_THREADS
690 if (res < 0)
691 return posix_error_with_filename(path);
692 Py_INCREF(Py_None);
693 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000694}
695
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000696
Guido van Rossum21142a01999-01-08 21:05:37 +0000697#ifdef HAVE_FSYNC
698static char posix_fsync__doc__[] =
699"fsync(fildes) -> None\n\
700force write of file with filedescriptor to disk.";
701
702static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000703posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000704{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000705 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000706}
707#endif /* HAVE_FSYNC */
708
709#ifdef HAVE_FDATASYNC
710static char posix_fdatasync__doc__[] =
711"fdatasync(fildes) -> None\n\
712force write of file with filedescriptor to disk.\n\
713 does not force update of metadata.";
714
715static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000716posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000717{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000718 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000719}
720#endif /* HAVE_FDATASYNC */
721
722
Fredrik Lundh10723342000-07-10 16:38:09 +0000723#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000724static char posix_chown__doc__[] =
725"chown(path, uid, gid) -> None\n\
726Change the owner and group id of path to the numeric uid and gid.";
727
Barry Warsaw53699e91996-12-10 23:23:01 +0000728static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000729posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000730{
Fredrik Lundh44328e62000-07-10 15:59:30 +0000731 char *path;
732 int uid, gid;
733 int res;
734 if (!PyArg_ParseTuple(args, "sii:chown", &path, &uid, &gid))
735 return NULL;
736 Py_BEGIN_ALLOW_THREADS
737 res = chown(path, (uid_t) uid, (gid_t) gid);
738 Py_END_ALLOW_THREADS
739 if (res < 0)
740 return posix_error_with_filename(path);
741 Py_INCREF(Py_None);
742 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000743}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000744#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000745
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000746
Guido van Rossum36bc6801995-06-14 22:54:23 +0000747#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000748static char posix_getcwd__doc__[] =
749"getcwd() -> path\n\
750Return a string representing the current working directory.";
751
Barry Warsaw53699e91996-12-10 23:23:01 +0000752static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000753posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000754{
755 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000756 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000757 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000758 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000759 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000760 res = getcwd(buf, sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +0000761 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000762 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000763 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000764 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000765}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000766#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000767
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000768
Guido van Rossumb6775db1994-08-01 11:34:53 +0000769#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000770static char posix_link__doc__[] =
771"link(src, dst) -> None\n\
772Create a hard link to a file.";
773
Barry Warsaw53699e91996-12-10 23:23:01 +0000774static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000775posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000776{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000777 return posix_2str(args, "ss:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000778}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000779#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000780
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000781
782static char posix_listdir__doc__[] =
783"listdir(path) -> list_of_strings\n\
784Return a list containing the names of the entries in the directory.\n\
785\n\
786 path: path of directory to list\n\
787\n\
788The list is in arbitrary order. It does not include the special\n\
789entries '.' and '..' even if they are present in the directory.";
790
Barry Warsaw53699e91996-12-10 23:23:01 +0000791static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000792posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000793{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000794 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000795 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000796#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000797
Guido van Rossumb6775db1994-08-01 11:34:53 +0000798 char *name;
799 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000800 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000801 HANDLE hFindFile;
802 WIN32_FIND_DATA FileData;
803 char namebuf[MAX_PATH+5];
804
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000805 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000806 return NULL;
807 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000808 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000809 return NULL;
810 }
811 strcpy(namebuf, name);
812 if (namebuf[len-1] != '/' && namebuf[len-1] != '\\')
813 namebuf[len++] = '/';
814 strcpy(namebuf + len, "*.*");
815
Barry Warsaw53699e91996-12-10 23:23:01 +0000816 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000817 return NULL;
818
819 hFindFile = FindFirstFile(namebuf, &FileData);
820 if (hFindFile == INVALID_HANDLE_VALUE) {
821 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000822 if (errno == ERROR_FILE_NOT_FOUND)
823 return PyList_New(0);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000824 return win32_error("FindFirstFile", name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000825 }
826 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000827 if (FileData.cFileName[0] == '.' &&
828 (FileData.cFileName[1] == '\0' ||
829 FileData.cFileName[1] == '.' &&
830 FileData.cFileName[2] == '\0'))
831 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +0000832 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000833 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000834 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000835 d = NULL;
836 break;
837 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000838 if (PyList_Append(d, v) != 0) {
839 Py_DECREF(v);
840 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000841 d = NULL;
842 break;
843 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000844 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000845 } while (FindNextFile(hFindFile, &FileData) == TRUE);
846
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000847 if (FindClose(hFindFile) == FALSE)
848 return win32_error("FindClose", name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000849
850 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000851
Guido van Rossum8d665e61996-06-26 18:22:49 +0000852#else /* !MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000853#ifdef _MSC_VER /* 16-bit Windows */
854
855#ifndef MAX_PATH
856#define MAX_PATH 250
857#endif
858 char *name, *pt;
859 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000860 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000861 char namebuf[MAX_PATH+5];
862 struct _find_t ep;
863
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000864 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000865 return NULL;
866 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000867 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000868 return NULL;
869 }
870 strcpy(namebuf, name);
871 for (pt = namebuf; *pt; pt++)
872 if (*pt == '/')
873 *pt = '\\';
874 if (namebuf[len-1] != '\\')
875 namebuf[len++] = '\\';
876 strcpy(namebuf + len, "*.*");
877
Barry Warsaw53699e91996-12-10 23:23:01 +0000878 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000879 return NULL;
880
881 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +0000882 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
883 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000884 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000885 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000886 }
887 do {
888 if (ep.name[0] == '.' &&
889 (ep.name[1] == '\0' ||
890 ep.name[1] == '.' &&
891 ep.name[2] == '\0'))
892 continue;
893 strcpy(namebuf, ep.name);
894 for (pt = namebuf; *pt; pt++)
895 if (isupper(*pt))
896 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +0000897 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000898 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000899 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000900 d = NULL;
901 break;
902 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000903 if (PyList_Append(d, v) != 0) {
904 Py_DECREF(v);
905 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000906 d = NULL;
907 break;
908 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000909 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000910 } while (_dos_findnext(&ep) == 0);
911
912 return d;
913
914#else
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000915#if defined(PYOS_OS2)
916
917#ifndef MAX_PATH
918#define MAX_PATH CCHMAXPATH
919#endif
920 char *name, *pt;
921 int len;
922 PyObject *d, *v;
923 char namebuf[MAX_PATH+5];
924 HDIR hdir = 1;
925 ULONG srchcnt = 1;
926 FILEFINDBUF3 ep;
927 APIRET rc;
928
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000929 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000930 return NULL;
931 if (len >= MAX_PATH) {
932 PyErr_SetString(PyExc_ValueError, "path too long");
933 return NULL;
934 }
935 strcpy(namebuf, name);
936 for (pt = namebuf; *pt; pt++)
937 if (*pt == '/')
938 *pt = '\\';
939 if (namebuf[len-1] != '\\')
940 namebuf[len++] = '\\';
941 strcpy(namebuf + len, "*.*");
942
943 if ((d = PyList_New(0)) == NULL)
944 return NULL;
945
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000946 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
947 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000948 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000949 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
950 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
951 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000952
953 if (rc != NO_ERROR) {
954 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000955 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000956 }
957
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000958 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000959 do {
960 if (ep.achName[0] == '.'
961 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000962 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000963
964 strcpy(namebuf, ep.achName);
965
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000966 /* Leave Case of Name Alone -- In Native Form */
967 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000968
969 v = PyString_FromString(namebuf);
970 if (v == NULL) {
971 Py_DECREF(d);
972 d = NULL;
973 break;
974 }
975 if (PyList_Append(d, v) != 0) {
976 Py_DECREF(v);
977 Py_DECREF(d);
978 d = NULL;
979 break;
980 }
981 Py_DECREF(v);
982 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
983 }
984
985 return d;
986#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000987
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000988 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +0000989 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000990 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000991 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000992 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000993 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000994 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000995 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000996 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000997 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000998 closedir(dirp);
999 return NULL;
1000 }
1001 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001002 if (ep->d_name[0] == '.' &&
1003 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001004 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001005 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001006 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001007 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001008 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001009 d = NULL;
1010 break;
1011 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001012 if (PyList_Append(d, v) != 0) {
1013 Py_DECREF(v);
1014 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001015 d = NULL;
1016 break;
1017 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001018 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001019 }
1020 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001021
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001022 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001023
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001024#endif /* !PYOS_OS2 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001025#endif /* !_MSC_VER */
Guido van Rossum8d665e61996-06-26 18:22:49 +00001026#endif /* !MS_WIN32 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001027}
1028
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001029static char posix_mkdir__doc__[] =
1030"mkdir(path [, mode=0777]) -> None\n\
1031Create a directory.";
1032
Barry Warsaw53699e91996-12-10 23:23:01 +00001033static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001034posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001035{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001036 int res;
1037 char *path;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001038 int mode = 0777;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001039 if (!PyArg_ParseTuple(args, "s|i:mkdir", &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001040 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001041 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001042#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001043 res = mkdir(path);
1044#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001045 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001046#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001047 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001048 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001049 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001050 Py_INCREF(Py_None);
1051 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001052}
1053
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001054
Guido van Rossumb6775db1994-08-01 11:34:53 +00001055#ifdef HAVE_NICE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001056static char posix_nice__doc__[] =
1057"nice(inc) -> new_priority\n\
1058Decrease the priority of process and return new priority.";
1059
Barry Warsaw53699e91996-12-10 23:23:01 +00001060static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001061posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001062{
1063 int increment, value;
1064
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001065 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001066 return NULL;
1067 value = nice(increment);
1068 if (value == -1)
1069 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001070 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001071}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001072#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001073
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001074
1075static char posix_rename__doc__[] =
1076"rename(old, new) -> None\n\
1077Rename a file or directory.";
1078
Barry Warsaw53699e91996-12-10 23:23:01 +00001079static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001080posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001081{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001082 return posix_2str(args, "ss:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001083}
1084
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001085
1086static char posix_rmdir__doc__[] =
1087"rmdir(path) -> None\n\
1088Remove a directory.";
1089
Barry Warsaw53699e91996-12-10 23:23:01 +00001090static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001091posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001092{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001093 return posix_1str(args, "s:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001094}
1095
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001096
1097static char posix_stat__doc__[] =
1098"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1099Perform a stat system call on the given path.";
1100
Barry Warsaw53699e91996-12-10 23:23:01 +00001101static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001102posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001103{
Fred Drake699f3522000-06-29 21:12:41 +00001104 return posix_do_stat(self, args, "s:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001105}
1106
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001107
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001108#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001109static char posix_system__doc__[] =
1110"system(command) -> exit_status\n\
1111Execute the command (a string) in a subshell.";
1112
Barry Warsaw53699e91996-12-10 23:23:01 +00001113static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001114posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001115{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001116 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001117 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001118 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001119 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001120 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001121 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001122 Py_END_ALLOW_THREADS
1123 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001124}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001125#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001126
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001127
1128static char posix_umask__doc__[] =
1129"umask(new_mask) -> old_mask\n\
1130Set the current numeric umask and return the previous umask.";
1131
Barry Warsaw53699e91996-12-10 23:23:01 +00001132static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001133posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001134{
1135 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001136 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001137 return NULL;
1138 i = umask(i);
1139 if (i < 0)
1140 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001141 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001142}
1143
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001144
1145static char posix_unlink__doc__[] =
1146"unlink(path) -> None\n\
1147Remove a file (same as remove(path)).";
1148
1149static char posix_remove__doc__[] =
1150"remove(path) -> None\n\
1151Remove a file (same as unlink(path)).";
1152
Barry Warsaw53699e91996-12-10 23:23:01 +00001153static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001154posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001155{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001156 return posix_1str(args, "s:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001157}
1158
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001159
Guido van Rossumb6775db1994-08-01 11:34:53 +00001160#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001161static char posix_uname__doc__[] =
1162"uname() -> (sysname, nodename, release, version, machine)\n\
1163Return a tuple identifying the current operating system.";
1164
Barry Warsaw53699e91996-12-10 23:23:01 +00001165static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001166posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001167{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001168 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001169 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001170 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001171 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001172 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001173 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001174 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001175 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001176 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001177 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001178 u.sysname,
1179 u.nodename,
1180 u.release,
1181 u.version,
1182 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001183}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001184#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001185
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001186
1187static char posix_utime__doc__[] =
1188"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001189utime(path, None) -> None\n\
1190Set the access and modified time of the file to the given values. If the\n\
1191second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001192
Barry Warsaw53699e91996-12-10 23:23:01 +00001193static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001194posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001195{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001196 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001197 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001198 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001199 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001200
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001201/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001202#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001203 struct utimbuf buf;
1204#define ATIME buf.actime
1205#define MTIME buf.modtime
1206#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001207#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001208 time_t buf[2];
1209#define ATIME buf[0]
1210#define MTIME buf[1]
1211#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001212#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001213
Barry Warsaw3cef8562000-05-01 16:17:24 +00001214 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001215 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001216 if (arg == Py_None) {
1217 /* optional time values not given */
1218 Py_BEGIN_ALLOW_THREADS
1219 res = utime(path, NULL);
1220 Py_END_ALLOW_THREADS
1221 }
1222 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1223 PyErr_SetString(PyExc_TypeError,
1224 "Second argument must be a 2-tuple of numbers.");
1225 return NULL;
1226 }
1227 else {
1228 ATIME = atime;
1229 MTIME = mtime;
1230 Py_BEGIN_ALLOW_THREADS
1231 res = utime(path, UTIME_ARG);
1232 Py_END_ALLOW_THREADS
1233 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001234 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001235 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001236 Py_INCREF(Py_None);
1237 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001238#undef UTIME_ARG
1239#undef ATIME
1240#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001241}
1242
Guido van Rossum85e3b011991-06-03 12:42:10 +00001243
Guido van Rossum3b066191991-06-04 19:40:25 +00001244/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001245
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001246static char posix__exit__doc__[] =
1247"_exit(status)\n\
1248Exit to the system with specified status, without normal exit processing.";
1249
Barry Warsaw53699e91996-12-10 23:23:01 +00001250static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001251posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001252{
1253 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001254 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001255 return NULL;
1256 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001257 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001258}
1259
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001260
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001261#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001262static char posix_execv__doc__[] =
1263"execv(path, args)\n\
1264Execute an executable path with arguments, replacing current process.\n\
1265\n\
1266 path: path of executable file\n\
1267 args: tuple or list of strings";
1268
Barry Warsaw53699e91996-12-10 23:23:01 +00001269static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001270posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001271{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001272 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001273 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001274 char **argvlist;
1275 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001276 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001277
Guido van Rossum89b33251993-10-22 14:26:06 +00001278 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001279 argv is a list or tuple of strings. */
1280
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001281 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001282 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001283 if (PyList_Check(argv)) {
1284 argc = PyList_Size(argv);
1285 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001286 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001287 else if (PyTuple_Check(argv)) {
1288 argc = PyTuple_Size(argv);
1289 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001290 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001291 else {
Guido van Rossum50422b42000-04-26 20:34:28 +00001292 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
1293 return NULL;
1294 }
1295
1296 if (argc == 0) {
1297 PyErr_SetString(PyExc_ValueError, "empty argument list");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001298 return NULL;
1299 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001300
Barry Warsaw53699e91996-12-10 23:23:01 +00001301 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001302 if (argvlist == NULL)
1303 return NULL;
1304 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001305 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1306 PyMem_DEL(argvlist);
Guido van Rossum50422b42000-04-26 20:34:28 +00001307 PyErr_SetString(PyExc_TypeError,
1308 "all arguments must be strings");
1309 return NULL;
1310
Guido van Rossum85e3b011991-06-03 12:42:10 +00001311 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001312 }
1313 argvlist[argc] = NULL;
1314
Guido van Rossumb6775db1994-08-01 11:34:53 +00001315#ifdef BAD_EXEC_PROTOTYPES
1316 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001317#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001318 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001319#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001320
Guido van Rossum85e3b011991-06-03 12:42:10 +00001321 /* If we get here it's definitely an error */
1322
Barry Warsaw53699e91996-12-10 23:23:01 +00001323 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001324 return posix_error();
1325}
1326
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001327
1328static char posix_execve__doc__[] =
1329"execve(path, args, env)\n\
1330Execute a path with arguments and environment, replacing current process.\n\
1331\n\
1332 path: path of executable file\n\
1333 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001334 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001335
Barry Warsaw53699e91996-12-10 23:23:01 +00001336static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001337posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001338{
1339 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001340 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001341 char **argvlist;
1342 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001343 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001344 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001345 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001346
1347 /* execve has three arguments: (path, argv, env), where
1348 argv is a list or tuple of strings and env is a dictionary
1349 like posix.environ. */
1350
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001351 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001352 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001353 if (PyList_Check(argv)) {
1354 argc = PyList_Size(argv);
1355 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001356 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001357 else if (PyTuple_Check(argv)) {
1358 argc = PyTuple_Size(argv);
1359 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001360 }
1361 else {
Barry Warsaw53699e91996-12-10 23:23:01 +00001362 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001363 return NULL;
1364 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001365 if (!PyMapping_Check(env)) {
1366 PyErr_SetString(PyExc_TypeError, "env must be mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001367 return NULL;
1368 }
1369
Guido van Rossum50422b42000-04-26 20:34:28 +00001370 if (argc == 0) {
1371 PyErr_SetString(PyExc_ValueError,
1372 "empty argument list");
1373 return NULL;
1374 }
1375
Barry Warsaw53699e91996-12-10 23:23:01 +00001376 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001377 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001378 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001379 return NULL;
1380 }
1381 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001382 if (!PyArg_Parse((*getitem)(argv, i),
Barry Warsaw43d68b81996-12-19 22:10:44 +00001383 "s;argv must be list of strings",
1384 &argvlist[i]))
1385 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001386 goto fail_1;
1387 }
1388 }
1389 argvlist[argc] = NULL;
1390
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001391 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001392 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001393 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001394 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001395 goto fail_1;
1396 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001397 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001398 keys = PyMapping_Keys(env);
1399 vals = PyMapping_Values(env);
1400 if (!keys || !vals)
1401 goto fail_2;
1402
1403 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001404 char *p, *k, *v;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001405
1406 key = PyList_GetItem(keys, pos);
1407 val = PyList_GetItem(vals, pos);
1408 if (!key || !val)
1409 goto fail_2;
1410
Barry Warsaw53699e91996-12-10 23:23:01 +00001411 if (!PyArg_Parse(key, "s;non-string key in env", &k) ||
Barry Warsaw43d68b81996-12-19 22:10:44 +00001412 !PyArg_Parse(val, "s;non-string value in env", &v))
1413 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001414 goto fail_2;
1415 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001416
1417#if defined(PYOS_OS2)
1418 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1419 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1420#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001421 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001422 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001423 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001424 goto fail_2;
1425 }
1426 sprintf(p, "%s=%s", k, v);
1427 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001428#if defined(PYOS_OS2)
1429 }
1430#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001431 }
1432 envlist[envc] = 0;
1433
Guido van Rossumb6775db1994-08-01 11:34:53 +00001434
1435#ifdef BAD_EXEC_PROTOTYPES
1436 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001437#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001438 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001439#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001440
1441 /* If we get here it's definitely an error */
1442
1443 (void) posix_error();
1444
1445 fail_2:
1446 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001447 PyMem_DEL(envlist[envc]);
1448 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001449 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001450 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001451 Py_XDECREF(vals);
1452 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001453 return NULL;
1454}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001455#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001456
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001457
Guido van Rossuma1065681999-01-25 23:20:23 +00001458#ifdef HAVE_SPAWNV
1459static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001460"spawnv(mode, path, args)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001461Execute an executable path with arguments, replacing current process.\n\
1462\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001463 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001464 path: path of executable file\n\
1465 args: tuple or list of strings";
1466
1467static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001468posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001469{
1470 char *path;
1471 PyObject *argv;
1472 char **argvlist;
1473 int mode, i, argc;
Fred Drake699f3522000-06-29 21:12:41 +00001474 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001475 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001476
1477 /* spawnv has three arguments: (mode, path, argv), where
1478 argv is a list or tuple of strings. */
1479
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001480 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001481 return NULL;
1482 if (PyList_Check(argv)) {
1483 argc = PyList_Size(argv);
1484 getitem = PyList_GetItem;
1485 }
1486 else if (PyTuple_Check(argv)) {
1487 argc = PyTuple_Size(argv);
1488 getitem = PyTuple_GetItem;
1489 }
1490 else {
Fred Drake137507e2000-06-01 02:02:46 +00001491 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001492 return NULL;
1493 }
1494
1495 argvlist = PyMem_NEW(char *, argc+1);
1496 if (argvlist == NULL)
1497 return NULL;
1498 for (i = 0; i < argc; i++) {
1499 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1500 PyMem_DEL(argvlist);
Fred Drake137507e2000-06-01 02:02:46 +00001501 PyErr_SetString(PyExc_TypeError,
1502 "all arguments must be strings");
1503 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001504 }
1505 }
1506 argvlist[argc] = NULL;
1507
Guido van Rossum246bc171999-02-01 23:54:31 +00001508 if (mode == _OLD_P_OVERLAY)
1509 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001510 spawnval = _spawnv(mode, path, argvlist);
Guido van Rossuma1065681999-01-25 23:20:23 +00001511
1512 PyMem_DEL(argvlist);
1513
Fred Drake699f3522000-06-29 21:12:41 +00001514 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001515 return posix_error();
1516 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001517#if SIZEOF_LONG == SIZEOF_VOID_P
1518 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001519#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001520 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001521#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001522}
1523
1524
1525static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001526"spawnve(mode, path, args, env)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001527Execute a path with arguments and environment, replacing current process.\n\
1528\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001529 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001530 path: path of executable file\n\
1531 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001532 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001533
1534static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001535posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001536{
1537 char *path;
1538 PyObject *argv, *env;
1539 char **argvlist;
1540 char **envlist;
1541 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1542 int mode, i, pos, argc, envc;
Fred Drake699f3522000-06-29 21:12:41 +00001543 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001544 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001545
1546 /* spawnve has four arguments: (mode, path, argv, env), where
1547 argv is a list or tuple of strings and env is a dictionary
1548 like posix.environ. */
1549
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001550 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001551 return NULL;
1552 if (PyList_Check(argv)) {
1553 argc = PyList_Size(argv);
1554 getitem = PyList_GetItem;
1555 }
1556 else if (PyTuple_Check(argv)) {
1557 argc = PyTuple_Size(argv);
1558 getitem = PyTuple_GetItem;
1559 }
1560 else {
1561 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
1562 return NULL;
1563 }
1564 if (!PyMapping_Check(env)) {
1565 PyErr_SetString(PyExc_TypeError, "env must be mapping object");
1566 return NULL;
1567 }
1568
1569 argvlist = PyMem_NEW(char *, argc+1);
1570 if (argvlist == NULL) {
1571 PyErr_NoMemory();
1572 return NULL;
1573 }
1574 for (i = 0; i < argc; i++) {
1575 if (!PyArg_Parse((*getitem)(argv, i),
1576 "s;argv must be list of strings",
1577 &argvlist[i]))
1578 {
1579 goto fail_1;
1580 }
1581 }
1582 argvlist[argc] = NULL;
1583
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001584 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001585 envlist = PyMem_NEW(char *, i + 1);
1586 if (envlist == NULL) {
1587 PyErr_NoMemory();
1588 goto fail_1;
1589 }
1590 envc = 0;
1591 keys = PyMapping_Keys(env);
1592 vals = PyMapping_Values(env);
1593 if (!keys || !vals)
1594 goto fail_2;
1595
1596 for (pos = 0; pos < i; pos++) {
1597 char *p, *k, *v;
1598
1599 key = PyList_GetItem(keys, pos);
1600 val = PyList_GetItem(vals, pos);
1601 if (!key || !val)
1602 goto fail_2;
1603
1604 if (!PyArg_Parse(key, "s;non-string key in env", &k) ||
1605 !PyArg_Parse(val, "s;non-string value in env", &v))
1606 {
1607 goto fail_2;
1608 }
1609 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1610 if (p == NULL) {
1611 PyErr_NoMemory();
1612 goto fail_2;
1613 }
1614 sprintf(p, "%s=%s", k, v);
1615 envlist[envc++] = p;
1616 }
1617 envlist[envc] = 0;
1618
Guido van Rossum246bc171999-02-01 23:54:31 +00001619 if (mode == _OLD_P_OVERLAY)
1620 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001621 spawnval = _spawnve(mode, path, argvlist, envlist);
1622 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001623 (void) posix_error();
1624 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001625#if SIZEOF_LONG == SIZEOF_VOID_P
1626 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001627#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001628 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001629#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001630
1631 fail_2:
1632 while (--envc >= 0)
1633 PyMem_DEL(envlist[envc]);
1634 PyMem_DEL(envlist);
1635 fail_1:
1636 PyMem_DEL(argvlist);
1637 Py_XDECREF(vals);
1638 Py_XDECREF(keys);
1639 return res;
1640}
1641#endif /* HAVE_SPAWNV */
1642
1643
Guido van Rossumad0ee831995-03-01 10:34:45 +00001644#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001645static char posix_fork__doc__[] =
1646"fork() -> pid\n\
1647Fork a child process.\n\
1648\n\
1649Return 0 to child process and PID of child to parent process.";
1650
Barry Warsaw53699e91996-12-10 23:23:01 +00001651static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001652posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001653{
1654 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001655 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001656 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001657 pid = fork();
1658 if (pid == -1)
1659 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001660 if (pid == 0)
1661 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001662 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001663}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001664#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001665
Fred Drake8cef4cf2000-06-28 16:40:38 +00001666#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1667#ifdef HAVE_PTY_H
1668#include <pty.h>
1669#else
1670#ifdef HAVE_LIBUTIL_H
1671#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001672#endif /* HAVE_LIBUTIL_H */
1673#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001674#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001675
Thomas Wouters70c21a12000-07-14 14:28:33 +00001676#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001677static char posix_openpty__doc__[] =
1678"openpty() -> (master_fd, slave_fd)\n\
1679Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1680
1681static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001682posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001683{
1684 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001685#ifndef HAVE_OPENPTY
1686 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001687#endif
1688
Fred Drake8cef4cf2000-06-28 16:40:38 +00001689 if (!PyArg_ParseTuple(args, ":openpty"))
1690 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001691
1692#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001693 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1694 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001695#else
1696 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1697 if (slave_name == NULL)
1698 return posix_error();
1699
1700 slave_fd = open(slave_name, O_RDWR);
1701 if (slave_fd < 0)
1702 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001703#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001704
Fred Drake8cef4cf2000-06-28 16:40:38 +00001705 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001706
Fred Drake8cef4cf2000-06-28 16:40:38 +00001707}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001708#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001709
1710#ifdef HAVE_FORKPTY
1711static char posix_forkpty__doc__[] =
1712"forkpty() -> (pid, master_fd)\n\
1713Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1714Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1715To both, return fd of newly opened pseudo-terminal.\n";
1716
1717static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001718posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001719{
1720 int master_fd, pid;
1721
1722 if (!PyArg_ParseTuple(args, ":forkpty"))
1723 return NULL;
1724 pid = forkpty(&master_fd, NULL, NULL, NULL);
1725 if (pid == -1)
1726 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001727 if (pid == 0)
1728 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001729 return Py_BuildValue("(ii)", pid, master_fd);
1730}
1731#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001732
Guido van Rossumad0ee831995-03-01 10:34:45 +00001733#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001734static char posix_getegid__doc__[] =
1735"getegid() -> egid\n\
1736Return the current process's effective group id.";
1737
Barry Warsaw53699e91996-12-10 23:23:01 +00001738static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001739posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001740{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001741 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001742 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001743 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001744}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001745#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001746
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001747
Guido van Rossumad0ee831995-03-01 10:34:45 +00001748#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001749static char posix_geteuid__doc__[] =
1750"geteuid() -> euid\n\
1751Return the current process's effective user id.";
1752
Barry Warsaw53699e91996-12-10 23:23:01 +00001753static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001754posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001755{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001756 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001757 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001758 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001759}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001760#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001761
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001762
Guido van Rossumad0ee831995-03-01 10:34:45 +00001763#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001764static char posix_getgid__doc__[] =
1765"getgid() -> gid\n\
1766Return the current process's group id.";
1767
Barry Warsaw53699e91996-12-10 23:23:01 +00001768static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001769posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001770{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001771 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001772 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001773 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001774}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001775#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001776
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001777
1778static char posix_getpid__doc__[] =
1779"getpid() -> pid\n\
1780Return the current process id";
1781
Barry Warsaw53699e91996-12-10 23:23:01 +00001782static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001783posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001784{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001785 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001786 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001787 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001788}
1789
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001790
Fred Drakec9680921999-12-13 16:37:25 +00001791#ifdef HAVE_GETGROUPS
1792static char posix_getgroups__doc__[] = "\
1793getgroups() -> list of group IDs\n\
1794Return list of supplemental group IDs for the process.";
1795
1796static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001797posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00001798{
1799 PyObject *result = NULL;
1800
1801 if (PyArg_ParseTuple(args, ":getgroups")) {
1802#ifdef NGROUPS_MAX
1803#define MAX_GROUPS NGROUPS_MAX
1804#else
1805 /* defined to be 16 on Solaris7, so this should be a small number */
1806#define MAX_GROUPS 64
1807#endif
1808 gid_t grouplist[MAX_GROUPS];
1809 int n;
1810
1811 n = getgroups(MAX_GROUPS, grouplist);
1812 if (n < 0)
1813 posix_error();
1814 else {
1815 result = PyList_New(n);
1816 if (result != NULL) {
1817 PyObject *o;
1818 int i;
1819 for (i = 0; i < n; ++i) {
1820 o = PyInt_FromLong((long)grouplist[i]);
1821 if (o == NULL) {
1822 Py_DECREF(result);
1823 result = NULL;
1824 break;
1825 }
1826 PyList_SET_ITEM(result, i, o);
1827 }
1828 }
1829 }
1830 }
1831 return result;
1832}
1833#endif
1834
Guido van Rossumb6775db1994-08-01 11:34:53 +00001835#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001836static char posix_getpgrp__doc__[] =
1837"getpgrp() -> pgrp\n\
1838Return the current process group id.";
1839
Barry Warsaw53699e91996-12-10 23:23:01 +00001840static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001841posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00001842{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001843 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00001844 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001845#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00001846 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001847#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00001848 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001849#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00001850}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001851#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00001852
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001853
Guido van Rossumb6775db1994-08-01 11:34:53 +00001854#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001855static char posix_setpgrp__doc__[] =
1856"setpgrp() -> None\n\
1857Make this process a session leader.";
1858
Barry Warsaw53699e91996-12-10 23:23:01 +00001859static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001860posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00001861{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001862 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00001863 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00001864#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00001865 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001866#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001867 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001868#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00001869 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001870 Py_INCREF(Py_None);
1871 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00001872}
1873
Guido van Rossumb6775db1994-08-01 11:34:53 +00001874#endif /* HAVE_SETPGRP */
1875
Guido van Rossumad0ee831995-03-01 10:34:45 +00001876#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001877static char posix_getppid__doc__[] =
1878"getppid() -> ppid\n\
1879Return the parent's process id.";
1880
Barry Warsaw53699e91996-12-10 23:23:01 +00001881static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001882posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001883{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001884 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001885 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001886 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001887}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001888#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001889
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001890
Fred Drake12c6e2d1999-12-14 21:25:03 +00001891#ifdef HAVE_GETLOGIN
1892static char posix_getlogin__doc__[] = "\
1893getlogin() -> string\n\
1894Return the actual login name.";
1895
1896static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001897posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00001898{
1899 PyObject *result = NULL;
1900
1901 if (PyArg_ParseTuple(args, ":getlogin")) {
1902 char *name = getlogin();
1903
1904 if (name == NULL)
1905 posix_error();
1906 else
1907 result = PyString_FromString(name);
1908 }
1909 return result;
1910}
1911#endif
1912
Guido van Rossumad0ee831995-03-01 10:34:45 +00001913#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001914static char posix_getuid__doc__[] =
1915"getuid() -> uid\n\
1916Return the current process's user id.";
1917
Barry Warsaw53699e91996-12-10 23:23:01 +00001918static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001919posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001920{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001921 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001922 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001923 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001924}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001925#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001926
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001927
Guido van Rossumad0ee831995-03-01 10:34:45 +00001928#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001929static char posix_kill__doc__[] =
1930"kill(pid, sig) -> None\n\
1931Kill a process with a signal.";
1932
Barry Warsaw53699e91996-12-10 23:23:01 +00001933static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001934posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001935{
1936 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001937 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001938 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001939#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001940 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
1941 APIRET rc;
1942 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001943 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001944
1945 } else if (sig == XCPT_SIGNAL_KILLPROC) {
1946 APIRET rc;
1947 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001948 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001949
1950 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001951 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001952#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00001953 if (kill(pid, sig) == -1)
1954 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001955#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001956 Py_INCREF(Py_None);
1957 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001958}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001959#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001960
Guido van Rossumc0125471996-06-28 18:55:32 +00001961#ifdef HAVE_PLOCK
1962
1963#ifdef HAVE_SYS_LOCK_H
1964#include <sys/lock.h>
1965#endif
1966
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001967static char posix_plock__doc__[] =
1968"plock(op) -> None\n\
1969Lock program segments into memory.";
1970
Barry Warsaw53699e91996-12-10 23:23:01 +00001971static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001972posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00001973{
1974 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001975 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00001976 return NULL;
1977 if (plock(op) == -1)
1978 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001979 Py_INCREF(Py_None);
1980 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00001981}
1982#endif
1983
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001984
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001985#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001986static char posix_popen__doc__[] =
1987"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
1988Open a pipe to/from a command returning a file object.";
1989
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001990#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001991static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001992async_system(const char *command)
1993{
1994 char *p, errormsg[256], args[1024];
1995 RESULTCODES rcodes;
1996 APIRET rc;
1997 char *shell = getenv("COMSPEC");
1998 if (!shell)
1999 shell = "cmd";
2000
2001 strcpy(args, shell);
2002 p = &args[ strlen(args)+1 ];
2003 strcpy(p, "/c ");
2004 strcat(p, command);
2005 p += strlen(p) + 1;
2006 *p = '\0';
2007
2008 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002009 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002010 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002011 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002012 &rcodes, shell);
2013 return rc;
2014}
2015
Guido van Rossumd48f2521997-12-05 22:19:34 +00002016static FILE *
2017popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002018{
2019 HFILE rhan, whan;
2020 FILE *retfd = NULL;
2021 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2022
Guido van Rossumd48f2521997-12-05 22:19:34 +00002023 if (rc != NO_ERROR) {
2024 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002025 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002026 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002027
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002028 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2029 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002030
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002031 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2032 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002033
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002034 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2035 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002036
2037 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002038 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002039 }
2040
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002041 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2042 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002043
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002044 close(oldfd); /* And Close Saved STDOUT Handle */
2045 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002046
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002047 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2048 int oldfd = dup(0); /* Save STDIN 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(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002052
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002053 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2054 DosClose(rhan); /* Close Now-Unused Pipe Read 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(whan, mode); /* And Return Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002058 }
2059
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002060 dup2(oldfd, 0); /* Reconnect STDIN 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 STDIN Handle */
2064 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002065
Guido van Rossumd48f2521997-12-05 22:19:34 +00002066 } else {
2067 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002068 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002069 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002070}
2071
2072static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002073posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002074{
2075 char *name;
2076 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002077 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002078 FILE *fp;
2079 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002080 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002081 return NULL;
2082 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002083 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002084 Py_END_ALLOW_THREADS
2085 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002086 return os2_error(err);
2087
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002088 f = PyFile_FromFile(fp, name, mode, fclose);
2089 if (f != NULL)
2090 PyFile_SetBufSize(f, bufsize);
2091 return f;
2092}
2093
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002094#elif defined(MS_WIN32)
2095
2096/*
2097 * Portable 'popen' replacement for Win32.
2098 *
2099 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2100 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Fredrik Lundh56055a42000-07-23 19:47:12 +00002101 * Return code handling by David Bolen.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002102 */
2103
2104#include <malloc.h>
2105#include <io.h>
2106#include <fcntl.h>
2107
2108/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2109#define POPEN_1 1
2110#define POPEN_2 2
2111#define POPEN_3 3
2112#define POPEN_4 4
2113
2114static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002115static int _PyPclose(FILE *file);
2116
2117/*
2118 * Internal dictionary mapping popen* file pointers to process handles,
2119 * in order to maintain a link to the process handle until the file is
2120 * closed, at which point the process exit code is returned to the caller.
2121 */
2122static PyObject *_PyPopenProcs = NULL;
2123
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002124
2125/* popen that works from a GUI.
2126 *
2127 * The result of this function is a pipe (file) connected to the
2128 * processes stdin or stdout, depending on the requested mode.
2129 */
2130
2131static PyObject *
2132posix_popen(PyObject *self, PyObject *args)
2133{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002134 PyObject *f, *s;
2135 int tm = 0;
2136
2137 char *cmdstring;
2138 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002139 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002140 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002141 return NULL;
2142
2143 s = PyTuple_New(0);
2144
2145 if (*mode == 'r')
2146 tm = _O_RDONLY;
2147 else if (*mode != 'w') {
2148 PyErr_SetString(PyExc_ValueError, "mode must be 'r' or 'w'");
2149 return NULL;
2150 } else
2151 tm = _O_WRONLY;
2152
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002153 if (bufsize != -1) {
2154 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2155 return NULL;
2156 }
2157
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002158 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002159 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002160 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002161 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002162 else
2163 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2164
2165 return f;
2166}
2167
2168/* Variation on win32pipe.popen
2169 *
2170 * The result of this function is a pipe (file) connected to the
2171 * process's stdin, and a pipe connected to the process's stdout.
2172 */
2173
2174static PyObject *
2175win32_popen2(PyObject *self, PyObject *args)
2176{
2177 PyObject *f;
2178 int tm=0;
2179
2180 char *cmdstring;
2181 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002182 int bufsize = -1;
2183 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002184 return NULL;
2185
2186 if (*mode == 't')
2187 tm = _O_TEXT;
2188 else if (*mode != 'b') {
2189 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2190 return NULL;
2191 } else
2192 tm = _O_BINARY;
2193
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002194 if (bufsize != -1) {
2195 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2196 return NULL;
2197 }
2198
2199 f = _PyPopen(cmdstring, tm, POPEN_2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002200
2201 return f;
2202}
2203
2204/*
2205 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002206 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002207 * The result of this function is 3 pipes - the process's stdin,
2208 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002209 */
2210
2211static PyObject *
2212win32_popen3(PyObject *self, PyObject *args)
2213{
2214 PyObject *f;
2215 int tm = 0;
2216
2217 char *cmdstring;
2218 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002219 int bufsize = -1;
2220 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002221 return NULL;
2222
2223 if (*mode == 't')
2224 tm = _O_TEXT;
2225 else if (*mode != 'b') {
2226 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2227 return NULL;
2228 } else
2229 tm = _O_BINARY;
2230
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002231 if (bufsize != -1) {
2232 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2233 return NULL;
2234 }
2235
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002236 f = _PyPopen(cmdstring, tm, POPEN_3);
2237
2238 return f;
2239}
2240
2241/*
2242 * Variation on win32pipe.popen
2243 *
2244 * The result of this function is 2 pipes - the processes stdin,
2245 * and stdout+stderr combined as a single pipe.
2246 */
2247
2248static PyObject *
2249win32_popen4(PyObject *self, PyObject *args)
2250{
2251 PyObject *f;
2252 int tm = 0;
2253
2254 char *cmdstring;
2255 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002256 int bufsize = -1;
2257 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002258 return NULL;
2259
2260 if (*mode == 't')
2261 tm = _O_TEXT;
2262 else if (*mode != 'b') {
2263 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2264 return NULL;
2265 } else
2266 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002267
2268 if (bufsize != -1) {
2269 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2270 return NULL;
2271 }
2272
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002273 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002274
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002275 return f;
2276}
2277
2278static int
Fredrik Lundh56055a42000-07-23 19:47:12 +00002279_PyPopenCreateProcess(char *cmdstring, FILE *file,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002280 HANDLE hStdin,
2281 HANDLE hStdout,
2282 HANDLE hStderr)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002283{
2284 PROCESS_INFORMATION piProcInfo;
2285 STARTUPINFO siStartInfo;
2286 char *s1,*s2, *s3 = " /c ";
2287 const char *szConsoleSpawn = "w9xpopen.exe \"";
2288 int i;
2289 int x;
2290
2291 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
2292 s1 = (char *)_alloca(i);
2293 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2294 return x;
2295 if (GetVersion() < 0x80000000) {
2296 /*
2297 * NT/2000
2298 */
2299 x = i + strlen(s3) + strlen(cmdstring) + 1;
2300 s2 = (char *)_alloca(x);
2301 ZeroMemory(s2, x);
2302 sprintf(s2, "%s%s%s", s1, s3, cmdstring);
2303 }
2304 else {
2305 /*
2306 * Oh gag, we're on Win9x. Use the workaround listed in
2307 * KB: Q150956
2308 */
2309 char modulepath[256];
2310 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2311 for (i = x = 0; modulepath[i]; i++)
2312 if (modulepath[i] == '\\')
2313 x = i+1;
2314 modulepath[x] = '\0';
2315 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2316 strlen(modulepath) +
2317 strlen(szConsoleSpawn) + 1;
2318 s2 = (char *)_alloca(x);
2319 ZeroMemory(s2, x);
2320 sprintf(
2321 s2,
2322 "%s%s%s%s%s\"",
2323 modulepath,
2324 szConsoleSpawn,
2325 s1,
2326 s3,
2327 cmdstring);
2328 }
2329 }
2330
2331 /* Could be an else here to try cmd.exe / command.com in the path
2332 Now we'll just error out.. */
2333 else
2334 return -1;
2335
2336 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2337 siStartInfo.cb = sizeof(STARTUPINFO);
2338 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2339 siStartInfo.hStdInput = hStdin;
2340 siStartInfo.hStdOutput = hStdout;
2341 siStartInfo.hStdError = hStderr;
2342 siStartInfo.wShowWindow = SW_HIDE;
2343
2344 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002345 s2,
2346 NULL,
2347 NULL,
2348 TRUE,
2349 CREATE_NEW_CONSOLE,
2350 NULL,
2351 NULL,
2352 &siStartInfo,
2353 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002354 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002355 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002356
2357 /*
2358 * Try to insert our process handle into the internal
2359 * dictionary so we can find it later when trying
2360 * to close this file.
2361 */
2362 if (!_PyPopenProcs)
2363 _PyPopenProcs = PyDict_New();
2364 if (_PyPopenProcs) {
2365 PyObject *hProcessObj, *fileObj;
2366
2367 hProcessObj = PyLong_FromVoidPtr(piProcInfo.hProcess);
2368 fileObj = PyLong_FromVoidPtr(file);
2369
2370 if (!hProcessObj || !fileObj ||
2371 PyDict_SetItem(_PyPopenProcs,
2372 fileObj, hProcessObj) < 0) {
2373 /* Insert failure - close handle to prevent leak */
2374 CloseHandle(piProcInfo.hProcess);
2375 }
2376 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002377 return TRUE;
2378 }
2379 return FALSE;
2380}
2381
2382/* The following code is based off of KB: Q190351 */
2383
2384static PyObject *
2385_PyPopen(char *cmdstring, int mode, int n)
2386{
2387 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2388 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
2389 hChildStderrRdDup; /* hChildStdoutWrDup; */
2390
2391 SECURITY_ATTRIBUTES saAttr;
2392 BOOL fSuccess;
2393 int fd1, fd2, fd3;
2394 FILE *f1, *f2, *f3;
2395 PyObject *f;
2396
2397 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2398 saAttr.bInheritHandle = TRUE;
2399 saAttr.lpSecurityDescriptor = NULL;
2400
2401 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2402 return win32_error("CreatePipe", NULL);
2403
2404 /* Create new output read handle and the input write handle. Set
2405 * the inheritance properties to FALSE. Otherwise, the child inherits
2406 * the these handles; resulting in non-closeable handles to the pipes
2407 * being created. */
2408 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002409 GetCurrentProcess(), &hChildStdinWrDup, 0,
2410 FALSE,
2411 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002412 if (!fSuccess)
2413 return win32_error("DuplicateHandle", NULL);
2414
2415 /* Close the inheritable version of ChildStdin
2416 that we're using. */
2417 CloseHandle(hChildStdinWr);
2418
2419 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2420 return win32_error("CreatePipe", NULL);
2421
2422 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002423 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2424 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002425 if (!fSuccess)
2426 return win32_error("DuplicateHandle", NULL);
2427
2428 /* Close the inheritable version of ChildStdout
2429 that we're using. */
2430 CloseHandle(hChildStdoutRd);
2431
2432 if (n != POPEN_4) {
2433 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2434 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002435 fSuccess = DuplicateHandle(GetCurrentProcess(),
2436 hChildStderrRd,
2437 GetCurrentProcess(),
2438 &hChildStderrRdDup, 0,
2439 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002440 if (!fSuccess)
2441 return win32_error("DuplicateHandle", NULL);
2442 /* Close the inheritable version of ChildStdErr that we're using. */
2443 CloseHandle(hChildStderrRd);
2444 }
2445
2446 switch (n) {
2447 case POPEN_1:
2448 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2449 case _O_WRONLY | _O_TEXT:
2450 /* Case for writing to child Stdin in text mode. */
2451 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2452 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002453 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002454 PyFile_SetBufSize(f, 0);
2455 /* We don't care about these pipes anymore, so close them. */
2456 CloseHandle(hChildStdoutRdDup);
2457 CloseHandle(hChildStderrRdDup);
2458 break;
2459
2460 case _O_RDONLY | _O_TEXT:
2461 /* Case for reading from child Stdout in text mode. */
2462 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2463 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002464 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002465 PyFile_SetBufSize(f, 0);
2466 /* We don't care about these pipes anymore, so close them. */
2467 CloseHandle(hChildStdinWrDup);
2468 CloseHandle(hChildStderrRdDup);
2469 break;
2470
2471 case _O_RDONLY | _O_BINARY:
2472 /* Case for readinig from child Stdout in binary mode. */
2473 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2474 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002475 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002476 PyFile_SetBufSize(f, 0);
2477 /* We don't care about these pipes anymore, so close them. */
2478 CloseHandle(hChildStdinWrDup);
2479 CloseHandle(hChildStderrRdDup);
2480 break;
2481
2482 case _O_WRONLY | _O_BINARY:
2483 /* Case for writing to child Stdin in binary mode. */
2484 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2485 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002486 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002487 PyFile_SetBufSize(f, 0);
2488 /* We don't care about these pipes anymore, so close them. */
2489 CloseHandle(hChildStdoutRdDup);
2490 CloseHandle(hChildStderrRdDup);
2491 break;
2492 }
2493 break;
2494
2495 case POPEN_2:
2496 case POPEN_4:
2497 {
2498 char *m1, *m2;
2499 PyObject *p1, *p2;
2500
2501 if (mode && _O_TEXT) {
2502 m1 = "r";
2503 m2 = "w";
2504 } else {
2505 m1 = "rb";
2506 m2 = "wb";
2507 }
2508
2509 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2510 f1 = _fdopen(fd1, m2);
2511 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2512 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002513 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002514 PyFile_SetBufSize(p1, 0);
2515 p2 = PyFile_FromFile(f2, cmdstring, m1, fclose);
2516 PyFile_SetBufSize(p2, 0);
2517
2518 if (n != 4)
2519 CloseHandle(hChildStderrRdDup);
2520
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002521 f = Py_BuildValue("OO",p1,p2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002522 break;
2523 }
2524
2525 case POPEN_3:
2526 {
2527 char *m1, *m2;
2528 PyObject *p1, *p2, *p3;
2529
2530 if (mode && _O_TEXT) {
2531 m1 = "r";
2532 m2 = "w";
2533 } else {
2534 m1 = "rb";
2535 m2 = "wb";
2536 }
2537
2538 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2539 f1 = _fdopen(fd1, m2);
2540 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2541 f2 = _fdopen(fd2, m1);
2542 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2543 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002544 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002545 p2 = PyFile_FromFile(f2, cmdstring, m1, fclose);
2546 p3 = PyFile_FromFile(f3, cmdstring, m1, fclose);
2547 PyFile_SetBufSize(p1, 0);
2548 PyFile_SetBufSize(p2, 0);
2549 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002550 f = Py_BuildValue("OOO",p1,p2,p3);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002551 break;
2552 }
2553 }
2554
2555 if (n == POPEN_4) {
2556 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh56055a42000-07-23 19:47:12 +00002557 f1,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002558 hChildStdinRd,
2559 hChildStdoutWr,
2560 hChildStdoutWr))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002561 return win32_error("CreateProcess", NULL);
2562 }
2563 else {
2564 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh56055a42000-07-23 19:47:12 +00002565 f1,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002566 hChildStdinRd,
2567 hChildStdoutWr,
2568 hChildStderrWr))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002569 return win32_error("CreateProcess", NULL);
2570 }
2571
2572 /* Child is launched. Close the parents copy of those pipe
2573 * handles that only the child should have open. You need to
2574 * make sure that no handles to the write end of the output pipe
2575 * are maintained in this process or else the pipe will not close
2576 * when the child process exits and the ReadFile will hang. */
2577
2578 if (!CloseHandle(hChildStdinRd))
2579 return win32_error("CloseHandle", NULL);
2580
2581 if (!CloseHandle(hChildStdoutWr))
2582 return win32_error("CloseHandle", NULL);
2583
2584 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2585 return win32_error("CloseHandle", NULL);
2586
2587 return f;
2588}
Fredrik Lundh56055a42000-07-23 19:47:12 +00002589
2590/*
2591 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2592 * exit code for the child process and return as a result of the close.
2593 */
2594static int _PyPclose(FILE *file)
2595{
Fredrik Lundh20318932000-07-26 17:29:12 +00002596 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002597 DWORD exit_code;
2598 HANDLE hProcess;
2599 PyObject *hProcessObj, *fileObj;
2600
Fredrik Lundh20318932000-07-26 17:29:12 +00002601 /* Close the file handle first, to ensure it can't block the
2602 * child from exiting when we wait for it below.
2603 */
2604 result = fclose(file);
2605
Fredrik Lundh56055a42000-07-23 19:47:12 +00002606 if (_PyPopenProcs) {
2607 fileObj = PyLong_FromVoidPtr(file);
2608 if (fileObj) {
2609 hProcessObj = PyDict_GetItem(_PyPopenProcs, fileObj);
2610 if (hProcessObj) {
2611 hProcess = PyLong_AsVoidPtr(hProcessObj);
Fredrik Lundh20318932000-07-26 17:29:12 +00002612 if (result != EOF &&
2613 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
2614 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00002615 /* Possible truncation here in 16-bit environments, but
2616 * real exit codes are just the lower byte in any event.
2617 */
2618 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002619 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00002620 /* Indicate failure - this will cause the file object
2621 * to raise an I/O error and translate the last Win32
2622 * error code from errno. We do have a problem with
2623 * last errors that overlap the normal errno table,
2624 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002625 */
Fredrik Lundh20318932000-07-26 17:29:12 +00002626 if (result != EOF) {
2627 /* If the error wasn't from the fclose(), then
2628 * set errno for the file object error handling.
2629 */
2630 errno = GetLastError();
2631 }
2632 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002633 }
2634
2635 /* Free up the native handle at this point */
2636 CloseHandle(hProcess);
2637
2638 /* Remove from dictionary and flush dictionary if empty */
2639 PyDict_DelItem(_PyPopenProcs, fileObj);
2640 if (PyDict_Size(_PyPopenProcs) == 0) {
2641 Py_DECREF(_PyPopenProcs);
2642 _PyPopenProcs = NULL;
2643 }
2644 } /* if hProcessObj */
2645 } /* if fileObj */
2646 } /* if _PyPopenProcs */
2647
Fredrik Lundh56055a42000-07-23 19:47:12 +00002648 return result;
2649}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002650#else
Barry Warsaw53699e91996-12-10 23:23:01 +00002651static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002652posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00002653{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002654 char *name;
2655 char *mode = "r";
2656 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00002657 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00002658 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002659 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00002660 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002661 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002662 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00002663 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00002664 if (fp == NULL)
2665 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002666 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002667 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00002668 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002669 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00002670}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002671#endif
2672
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002673#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00002674
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002675
Guido van Rossumb6775db1994-08-01 11:34:53 +00002676#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002677static char posix_setuid__doc__[] =
2678"setuid(uid) -> None\n\
2679Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00002680static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002681posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002682{
2683 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002684 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002685 return NULL;
2686 if (setuid(uid) < 0)
2687 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002688 Py_INCREF(Py_None);
2689 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002690}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002691#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002692
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002693
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00002694#ifdef HAVE_SETEUID
2695static char posix_seteuid__doc__[] =
2696"seteuid(uid) -> None\n\
2697Set the current process's effective user id.";
2698static PyObject *
2699posix_seteuid (PyObject *self, PyObject *args)
2700{
2701 int euid;
2702 if (!PyArg_ParseTuple(args, "i", &euid)) {
2703 return NULL;
2704 } else if (seteuid(euid) < 0) {
2705 return posix_error();
2706 } else {
2707 Py_INCREF(Py_None);
2708 return Py_None;
2709 }
2710}
2711#endif /* HAVE_SETEUID */
2712
2713#ifdef HAVE_SETEGID
2714static char posix_setegid__doc__[] =
2715"setegid(gid) -> None\n\
2716Set the current process's effective group id.";
2717static PyObject *
2718posix_setegid (PyObject *self, PyObject *args)
2719{
2720 int egid;
2721 if (!PyArg_ParseTuple(args, "i", &egid)) {
2722 return NULL;
2723 } else if (setegid(egid) < 0) {
2724 return posix_error();
2725 } else {
2726 Py_INCREF(Py_None);
2727 return Py_None;
2728 }
2729}
2730#endif /* HAVE_SETEGID */
2731
2732#ifdef HAVE_SETREUID
2733static char posix_setreuid__doc__[] =
2734"seteuid(ruid, euid) -> None\n\
2735Set the current process's real and effective user ids.";
2736static PyObject *
2737posix_setreuid (PyObject *self, PyObject *args)
2738{
2739 int ruid, euid;
2740 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
2741 return NULL;
2742 } else if (setreuid(ruid, euid) < 0) {
2743 return posix_error();
2744 } else {
2745 Py_INCREF(Py_None);
2746 return Py_None;
2747 }
2748}
2749#endif /* HAVE_SETREUID */
2750
2751#ifdef HAVE_SETREGID
2752static char posix_setregid__doc__[] =
2753"setegid(rgid, egid) -> None\n\
2754Set the current process's real and effective group ids.";
2755static PyObject *
2756posix_setregid (PyObject *self, PyObject *args)
2757{
2758 int rgid, egid;
2759 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
2760 return NULL;
2761 } else if (setregid(rgid, egid) < 0) {
2762 return posix_error();
2763 } else {
2764 Py_INCREF(Py_None);
2765 return Py_None;
2766 }
2767}
2768#endif /* HAVE_SETREGID */
2769
Guido van Rossumb6775db1994-08-01 11:34:53 +00002770#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002771static char posix_setgid__doc__[] =
2772"setgid(gid) -> None\n\
2773Set the current process's group id.";
2774
Barry Warsaw53699e91996-12-10 23:23:01 +00002775static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002776posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002777{
2778 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002779 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002780 return NULL;
2781 if (setgid(gid) < 0)
2782 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002783 Py_INCREF(Py_None);
2784 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002785}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002786#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002787
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002788
Guido van Rossumb6775db1994-08-01 11:34:53 +00002789#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002790static char posix_waitpid__doc__[] =
2791"waitpid(pid, options) -> (pid, status)\n\
2792Wait for completion of a give child process.";
2793
Barry Warsaw53699e91996-12-10 23:23:01 +00002794static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002795posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002796{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002797 int pid, options;
2798#ifdef UNION_WAIT
2799 union wait status;
2800#define status_i (status.w_status)
2801#else
2802 int status;
2803#define status_i status
2804#endif
2805 status_i = 0;
2806
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002807 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00002808 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002809 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00002810#ifdef NeXT
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002811 pid = wait4(pid, &status, options, NULL);
Guido van Rossume6a3aa61999-02-01 16:15:30 +00002812#else
2813 pid = waitpid(pid, &status, options);
2814#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002815 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00002816 if (pid == -1)
2817 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00002818 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002819 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00002820}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002821#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +00002822
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002823
Guido van Rossumad0ee831995-03-01 10:34:45 +00002824#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002825static char posix_wait__doc__[] =
2826"wait() -> (pid, status)\n\
2827Wait for completion of a child process.";
2828
Barry Warsaw53699e91996-12-10 23:23:01 +00002829static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002830posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00002831{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002832 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002833#ifdef UNION_WAIT
2834 union wait status;
2835#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00002836#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002837 int status;
2838#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00002839#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002840 if (!PyArg_ParseTuple(args, ":wait"))
2841 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002842 status_i = 0;
2843 Py_BEGIN_ALLOW_THREADS
2844 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00002845 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00002846 if (pid == -1)
2847 return posix_error();
2848 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002849 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002850#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00002851}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002852#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002853
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002854
2855static char posix_lstat__doc__[] =
2856"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
2857Like stat(path), but do not follow symbolic links.";
2858
Barry Warsaw53699e91996-12-10 23:23:01 +00002859static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002860posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002861{
Guido van Rossumb6775db1994-08-01 11:34:53 +00002862#ifdef HAVE_LSTAT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002863 return posix_do_stat(self, args, "s:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002864#else /* !HAVE_LSTAT */
Fred Drake699f3522000-06-29 21:12:41 +00002865 return posix_do_stat(self, args, "s:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002866#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002867}
2868
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002869
Guido van Rossumb6775db1994-08-01 11:34:53 +00002870#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002871static char posix_readlink__doc__[] =
2872"readlink(path) -> path\n\
2873Return a string representing the path to which the symbolic link points.";
2874
Barry Warsaw53699e91996-12-10 23:23:01 +00002875static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002876posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002877{
Guido van Rossumb6775db1994-08-01 11:34:53 +00002878 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002879 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002880 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002881 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002882 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002883 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00002884 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00002885 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002886 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00002887 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002888 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002889}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002890#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002891
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002892
Guido van Rossumb6775db1994-08-01 11:34:53 +00002893#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002894static char posix_symlink__doc__[] =
2895"symlink(src, dst) -> None\n\
2896Create a symbolic link.";
2897
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002898static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002899posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002900{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002901 return posix_2str(args, "ss:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002902}
2903#endif /* HAVE_SYMLINK */
2904
2905
2906#ifdef HAVE_TIMES
2907#ifndef HZ
2908#define HZ 60 /* Universal constant :-) */
2909#endif /* HZ */
2910
Guido van Rossumd48f2521997-12-05 22:19:34 +00002911#if defined(PYCC_VACPP) && defined(PYOS_OS2)
2912static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002913system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002914{
2915 ULONG value = 0;
2916
2917 Py_BEGIN_ALLOW_THREADS
2918 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
2919 Py_END_ALLOW_THREADS
2920
2921 return value;
2922}
2923
2924static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002925posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002926{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002927 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00002928 return NULL;
2929
2930 /* Currently Only Uptime is Provided -- Others Later */
2931 return Py_BuildValue("ddddd",
2932 (double)0 /* t.tms_utime / HZ */,
2933 (double)0 /* t.tms_stime / HZ */,
2934 (double)0 /* t.tms_cutime / HZ */,
2935 (double)0 /* t.tms_cstime / HZ */,
2936 (double)system_uptime() / 1000);
2937}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002938#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00002939static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002940posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00002941{
2942 struct tms t;
2943 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002944 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00002945 return NULL;
2946 errno = 0;
2947 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00002948 if (c == (clock_t) -1)
2949 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002950 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002951 (double)t.tms_utime / HZ,
2952 (double)t.tms_stime / HZ,
2953 (double)t.tms_cutime / HZ,
2954 (double)t.tms_cstime / HZ,
2955 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00002956}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002957#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002958#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002959
2960
Guido van Rossum87755a21996-09-07 00:59:43 +00002961#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00002962#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00002963static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002964posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00002965{
2966 FILETIME create, exit, kernel, user;
2967 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002968 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00002969 return NULL;
2970 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00002971 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
2972 /* The fields of a FILETIME structure are the hi and lo part
2973 of a 64-bit value expressed in 100 nanosecond units.
2974 1e7 is one second in such units; 1e-7 the inverse.
2975 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
2976 */
Barry Warsaw53699e91996-12-10 23:23:01 +00002977 return Py_BuildValue(
2978 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00002979 (double)(kernel.dwHighDateTime*429.4967296 +
2980 kernel.dwLowDateTime*1e-7),
2981 (double)(user.dwHighDateTime*429.4967296 +
2982 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00002983 (double)0,
2984 (double)0,
2985 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00002986}
Guido van Rossum8d665e61996-06-26 18:22:49 +00002987#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002988
2989#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00002990static char posix_times__doc__[] =
2991"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
2992Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002993#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00002994
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002995
Guido van Rossumb6775db1994-08-01 11:34:53 +00002996#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002997static char posix_setsid__doc__[] =
2998"setsid() -> None\n\
2999Call the system call setsid().";
3000
Barry Warsaw53699e91996-12-10 23:23:01 +00003001static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003002posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003003{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003004 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003005 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003006 if (setsid() < 0)
3007 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003008 Py_INCREF(Py_None);
3009 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003010}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003011#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003012
Guido van Rossumb6775db1994-08-01 11:34:53 +00003013#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003014static char posix_setpgid__doc__[] =
3015"setpgid(pid, pgrp) -> None\n\
3016Call the system call setpgid().";
3017
Barry Warsaw53699e91996-12-10 23:23:01 +00003018static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003019posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003020{
3021 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003022 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003023 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003024 if (setpgid(pid, pgrp) < 0)
3025 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003026 Py_INCREF(Py_None);
3027 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003028}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003029#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003030
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003031
Guido van Rossumb6775db1994-08-01 11:34:53 +00003032#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003033static char posix_tcgetpgrp__doc__[] =
3034"tcgetpgrp(fd) -> pgid\n\
3035Return the process group associated with the terminal given by a fd.";
3036
Barry Warsaw53699e91996-12-10 23:23:01 +00003037static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003038posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003039{
3040 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003041 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003042 return NULL;
3043 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003044 if (pgid < 0)
3045 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003046 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00003047}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003048#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00003049
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003050
Guido van Rossumb6775db1994-08-01 11:34:53 +00003051#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003052static char posix_tcsetpgrp__doc__[] =
3053"tcsetpgrp(fd, pgid) -> None\n\
3054Set the process group associated with the terminal given by a fd.";
3055
Barry Warsaw53699e91996-12-10 23:23:01 +00003056static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003057posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003058{
3059 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003060 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003061 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003062 if (tcsetpgrp(fd, pgid) < 0)
3063 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00003064 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00003065 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00003066}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003067#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00003068
Guido van Rossum687dd131993-05-17 08:34:16 +00003069/* Functions acting on file descriptors */
3070
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003071static char posix_open__doc__[] =
3072"open(filename, flag [, mode=0777]) -> fd\n\
3073Open a file (for low level IO).";
3074
Barry Warsaw53699e91996-12-10 23:23:01 +00003075static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003076posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003077{
3078 char *file;
3079 int flag;
3080 int mode = 0777;
3081 int fd;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003082 if (!PyArg_ParseTuple(args, "si|i", &file, &flag, &mode))
3083 return NULL;
3084
Barry Warsaw53699e91996-12-10 23:23:01 +00003085 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003086 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003087 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003088 if (fd < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003089 return posix_error_with_filename(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00003090 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003091}
3092
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003093
3094static char posix_close__doc__[] =
3095"close(fd) -> None\n\
3096Close a file descriptor (for low level IO).";
3097
Barry Warsaw53699e91996-12-10 23:23:01 +00003098static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003099posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003100{
3101 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003102 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003103 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003104 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003105 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003106 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003107 if (res < 0)
3108 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003109 Py_INCREF(Py_None);
3110 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003111}
3112
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003113
3114static char posix_dup__doc__[] =
3115"dup(fd) -> fd2\n\
3116Return a duplicate of a file descriptor.";
3117
Barry Warsaw53699e91996-12-10 23:23:01 +00003118static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003119posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003120{
3121 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003122 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003123 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003124 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003125 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003126 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003127 if (fd < 0)
3128 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003129 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003130}
3131
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003132
3133static char posix_dup2__doc__[] =
3134"dup2(fd, fd2) -> None\n\
3135Duplicate file descriptor.";
3136
Barry Warsaw53699e91996-12-10 23:23:01 +00003137static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003138posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003139{
3140 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003141 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00003142 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003143 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003144 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00003145 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003146 if (res < 0)
3147 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003148 Py_INCREF(Py_None);
3149 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003150}
3151
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003152
3153static char posix_lseek__doc__[] =
3154"lseek(fd, pos, how) -> newpos\n\
3155Set the current position of a file descriptor.";
3156
Barry Warsaw53699e91996-12-10 23:23:01 +00003157static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003158posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003159{
3160 int fd, how;
Fred Drake699f3522000-06-29 21:12:41 +00003161#ifdef MS_WIN64
3162 LONG_LONG pos, res;
3163#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003164 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003165#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003166 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003167 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003168 return NULL;
3169#ifdef SEEK_SET
3170 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3171 switch (how) {
3172 case 0: how = SEEK_SET; break;
3173 case 1: how = SEEK_CUR; break;
3174 case 2: how = SEEK_END; break;
3175 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003176#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003177
3178#if !defined(HAVE_LARGEFILE_SUPPORT)
3179 pos = PyInt_AsLong(posobj);
3180#else
3181 pos = PyLong_Check(posobj) ?
3182 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3183#endif
3184 if (PyErr_Occurred())
3185 return NULL;
3186
Barry Warsaw53699e91996-12-10 23:23:01 +00003187 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003188#ifdef MS_WIN64
3189 res = _lseeki64(fd, pos, how);
3190#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003191 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003192#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003193 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003194 if (res < 0)
3195 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003196
3197#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003198 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003199#else
3200 return PyLong_FromLongLong(res);
3201#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003202}
3203
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003204
3205static char posix_read__doc__[] =
3206"read(fd, buffersize) -> string\n\
3207Read a file descriptor.";
3208
Barry Warsaw53699e91996-12-10 23:23:01 +00003209static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003210posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003211{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003212 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003213 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003214 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003215 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003216 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003217 if (buffer == NULL)
3218 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003219 Py_BEGIN_ALLOW_THREADS
3220 n = read(fd, PyString_AsString(buffer), size);
3221 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003222 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003223 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003224 return posix_error();
3225 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003226 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003227 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003228 return buffer;
3229}
3230
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003231
3232static char posix_write__doc__[] =
3233"write(fd, string) -> byteswritten\n\
3234Write a string to a file descriptor.";
3235
Barry Warsaw53699e91996-12-10 23:23:01 +00003236static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003237posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003238{
3239 int fd, size;
3240 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003241 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003242 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003243 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003244 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003245 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003246 if (size < 0)
3247 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003248 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003249}
3250
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003251
3252static char posix_fstat__doc__[]=
3253"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3254Like stat(), but for an open file descriptor.";
3255
Barry Warsaw53699e91996-12-10 23:23:01 +00003256static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003257posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003258{
3259 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003260 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003261 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003262 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003263 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003264 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003265 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003266 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003267 if (res != 0)
3268 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00003269
3270 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003271}
3272
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003273
3274static char posix_fdopen__doc__[] =
3275"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3276Return an open file object connected to a file descriptor.";
3277
Barry Warsaw53699e91996-12-10 23:23:01 +00003278static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003279posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003280{
Guido van Rossum687dd131993-05-17 08:34:16 +00003281 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003282 char *mode = "r";
3283 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003284 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003285 PyObject *f;
3286 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003287 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003288
Barry Warsaw53699e91996-12-10 23:23:01 +00003289 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003290 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003291 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003292 if (fp == NULL)
3293 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003294 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003295 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003296 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003297 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003298}
3299
Skip Montanaro1517d842000-07-19 14:34:14 +00003300static char posix_isatty__doc__[] =
3301"isatty(fd) -> Boolean\n\
3302Return true if the file descriptor 'fd' is an open file descriptor\n\
3303connected to a terminal.";
3304
3305static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00003306posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00003307{
3308 int fd;
3309 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3310 return NULL;
3311 return Py_BuildValue("i", isatty(fd));
3312}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003313
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003314#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003315static char posix_pipe__doc__[] =
3316"pipe() -> (read_end, write_end)\n\
3317Create a pipe.";
3318
Barry Warsaw53699e91996-12-10 23:23:01 +00003319static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003320posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003321{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003322#if defined(PYOS_OS2)
3323 HFILE read, write;
3324 APIRET rc;
3325
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003326 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003327 return NULL;
3328
3329 Py_BEGIN_ALLOW_THREADS
3330 rc = DosCreatePipe( &read, &write, 4096);
3331 Py_END_ALLOW_THREADS
3332 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003333 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003334
3335 return Py_BuildValue("(ii)", read, write);
3336#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003337#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003338 int fds[2];
3339 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003340 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003341 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003342 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003343 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003344 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003345 if (res != 0)
3346 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003347 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003348#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003349 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003350 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003351 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003352 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003353 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003354 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003355 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003356 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003357 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003358 return win32_error("CreatePipe", NULL);
Fred Drake699f3522000-06-29 21:12:41 +00003359 read_fd = _open_osfhandle((intptr_t)read, 0);
3360 write_fd = _open_osfhandle((intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003361 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003362#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003363#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003364}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003365#endif /* HAVE_PIPE */
3366
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003367
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003368#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003369static char posix_mkfifo__doc__[] =
3370"mkfifo(file, [, mode=0666]) -> None\n\
3371Create a FIFO (a POSIX named pipe).";
3372
Barry Warsaw53699e91996-12-10 23:23:01 +00003373static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003374posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003375{
3376 char *file;
3377 int mode = 0666;
3378 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003379 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003380 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003381 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003382 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003383 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003384 if (res < 0)
3385 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003386 Py_INCREF(Py_None);
3387 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003388}
3389#endif
3390
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003391
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003392#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003393static char posix_ftruncate__doc__[] =
3394"ftruncate(fd, length) -> None\n\
3395Truncate a file to a specified length.";
3396
Barry Warsaw53699e91996-12-10 23:23:01 +00003397static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003398posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003399{
3400 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003401 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003402 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003403 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003404
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003405 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003406 return NULL;
3407
3408#if !defined(HAVE_LARGEFILE_SUPPORT)
3409 length = PyInt_AsLong(lenobj);
3410#else
3411 length = PyLong_Check(lenobj) ?
3412 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3413#endif
3414 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003415 return NULL;
3416
Barry Warsaw53699e91996-12-10 23:23:01 +00003417 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003418 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003419 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003420 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003421 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003422 return NULL;
3423 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003424 Py_INCREF(Py_None);
3425 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003426}
3427#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003428
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003429#ifdef NeXT
3430#define HAVE_PUTENV
3431/* Steve Spicklemire got this putenv from NeXTAnswers */
3432static int
3433putenv(char *newval)
3434{
3435 extern char **environ;
3436
3437 static int firstTime = 1;
3438 char **ep;
3439 char *cp;
3440 int esiz;
3441 char *np;
3442
3443 if (!(np = strchr(newval, '=')))
3444 return 1;
3445 *np = '\0';
3446
3447 /* look it up */
3448 for (ep=environ ; *ep ; ep++)
3449 {
3450 /* this should always be true... */
3451 if (cp = strchr(*ep, '='))
3452 {
3453 *cp = '\0';
3454 if (!strcmp(*ep, newval))
3455 {
3456 /* got it! */
3457 *cp = '=';
3458 break;
3459 }
3460 *cp = '=';
3461 }
3462 else
3463 {
3464 *np = '=';
3465 return 1;
3466 }
3467 }
3468
3469 *np = '=';
3470 if (*ep)
3471 {
3472 /* the string was already there:
3473 just replace it with the new one */
3474 *ep = newval;
3475 return 0;
3476 }
3477
3478 /* expand environ by one */
3479 for (esiz=2, ep=environ ; *ep ; ep++)
3480 esiz++;
3481 if (firstTime)
3482 {
3483 char **epp;
3484 char **newenv;
3485 if (!(newenv = malloc(esiz * sizeof(char *))))
3486 return 1;
3487
3488 for (ep=environ, epp=newenv ; *ep ;)
3489 *epp++ = *ep++;
3490 *epp++ = newval;
3491 *epp = (char *) 0;
3492 environ = newenv;
3493 }
3494 else
3495 {
3496 if (!(environ = realloc(environ, esiz * sizeof(char *))))
3497 return 1;
3498 environ[esiz - 2] = newval;
3499 environ[esiz - 1] = (char *) 0;
3500 firstTime = 0;
3501 }
3502
3503 return 0;
3504}
Guido van Rossumc6ef2041997-08-21 02:30:45 +00003505#endif /* NeXT */
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003506
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003507
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003508#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003509static char posix_putenv__doc__[] =
3510"putenv(key, value) -> None\n\
3511Change or add an environment variable.";
3512
Guido van Rossumbcc20741998-08-04 22:53:56 +00003513#ifdef __BEOS__
3514/* We have putenv(), but not in the headers (as of PR2). - [cjh] */
3515int putenv( const char *str );
3516#endif
3517
Fred Drake762e2061999-08-26 17:23:54 +00003518/* Save putenv() parameters as values here, so we can collect them when they
3519 * get re-set with another call for the same key. */
3520static PyObject *posix_putenv_garbage;
3521
Barry Warsaw53699e91996-12-10 23:23:01 +00003522static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003523posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003524{
3525 char *s1, *s2;
3526 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00003527 PyObject *newstr;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003528
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003529 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003530 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003531
3532#if defined(PYOS_OS2)
3533 if (stricmp(s1, "BEGINLIBPATH") == 0) {
3534 APIRET rc;
3535
3536 if (strlen(s2) == 0) /* If New Value is an Empty String */
3537 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3538
3539 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
3540 if (rc != NO_ERROR)
3541 return os2_error(rc);
3542
3543 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
3544 APIRET rc;
3545
3546 if (strlen(s2) == 0) /* If New Value is an Empty String */
3547 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3548
3549 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
3550 if (rc != NO_ERROR)
3551 return os2_error(rc);
3552 } else {
3553#endif
3554
Fred Drake762e2061999-08-26 17:23:54 +00003555 /* XXX This can leak memory -- not easy to fix :-( */
3556 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
3557 if (newstr == NULL)
3558 return PyErr_NoMemory();
3559 new = PyString_AS_STRING(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003560 (void) sprintf(new, "%s=%s", s1, s2);
3561 if (putenv(new)) {
3562 posix_error();
3563 return NULL;
3564 }
Fred Drake762e2061999-08-26 17:23:54 +00003565 /* Install the first arg and newstr in posix_putenv_garbage;
3566 * this will cause previous value to be collected. This has to
3567 * happen after the real putenv() call because the old value
3568 * was still accessible until then. */
3569 if (PyDict_SetItem(posix_putenv_garbage,
3570 PyTuple_GET_ITEM(args, 0), newstr)) {
3571 /* really not much we can do; just leak */
3572 PyErr_Clear();
3573 }
3574 else {
3575 Py_DECREF(newstr);
3576 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003577
3578#if defined(PYOS_OS2)
3579 }
3580#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003581 Py_INCREF(Py_None);
3582 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003583}
Guido van Rossumb6a47161997-09-15 22:54:34 +00003584#endif /* putenv */
3585
3586#ifdef HAVE_STRERROR
3587static char posix_strerror__doc__[] =
3588"strerror(code) -> string\n\
3589Translate an error code to a message string.";
3590
3591PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003592posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00003593{
3594 int code;
3595 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003596 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00003597 return NULL;
3598 message = strerror(code);
3599 if (message == NULL) {
3600 PyErr_SetString(PyExc_ValueError,
3601 "strerror code out of range");
3602 return NULL;
3603 }
3604 return PyString_FromString(message);
3605}
3606#endif /* strerror */
3607
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003608
Guido van Rossumc9641791998-08-04 15:26:23 +00003609#ifdef HAVE_SYS_WAIT_H
3610
3611#ifdef WIFSTOPPED
3612static char posix_WIFSTOPPED__doc__[] =
3613"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003614Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003615
3616static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003617posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003618{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003619#ifdef UNION_WAIT
3620 union wait status;
3621#define status_i (status.w_status)
3622#else
3623 int status;
3624#define status_i status
3625#endif
3626 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003627
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003628 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003629 {
3630 return NULL;
3631 }
3632
3633 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003634#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003635}
3636#endif /* WIFSTOPPED */
3637
3638#ifdef WIFSIGNALED
3639static char posix_WIFSIGNALED__doc__[] =
3640"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00003641Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003642
3643static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003644posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003645{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003646#ifdef UNION_WAIT
3647 union wait status;
3648#define status_i (status.w_status)
3649#else
3650 int status;
3651#define status_i status
3652#endif
3653 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003654
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003655 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003656 {
3657 return NULL;
3658 }
3659
3660 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003661#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003662}
3663#endif /* WIFSIGNALED */
3664
3665#ifdef WIFEXITED
3666static char posix_WIFEXITED__doc__[] =
3667"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003668Return true if the process returning 'status' exited using the exit()\n\
3669system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003670
3671static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003672posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003673{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003674#ifdef UNION_WAIT
3675 union wait status;
3676#define status_i (status.w_status)
3677#else
3678 int status;
3679#define status_i status
3680#endif
3681 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003682
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003683 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003684 {
3685 return NULL;
3686 }
3687
3688 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003689#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003690}
3691#endif /* WIFEXITED */
3692
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003693#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00003694static char posix_WEXITSTATUS__doc__[] =
3695"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003696Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003697
3698static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003699posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003700{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003701#ifdef UNION_WAIT
3702 union wait status;
3703#define status_i (status.w_status)
3704#else
3705 int status;
3706#define status_i status
3707#endif
3708 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003709
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003710 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003711 {
3712 return NULL;
3713 }
3714
3715 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003716#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003717}
3718#endif /* WEXITSTATUS */
3719
3720#ifdef WTERMSIG
3721static char posix_WTERMSIG__doc__[] =
3722"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003723Return the signal that terminated the process that provided the 'status'\n\
3724value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003725
3726static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003727posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003728{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003729#ifdef UNION_WAIT
3730 union wait status;
3731#define status_i (status.w_status)
3732#else
3733 int status;
3734#define status_i status
3735#endif
3736 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003737
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003738 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003739 {
3740 return NULL;
3741 }
3742
3743 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003744#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003745}
3746#endif /* WTERMSIG */
3747
3748#ifdef WSTOPSIG
3749static char posix_WSTOPSIG__doc__[] =
3750"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003751Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003752
3753static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003754posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003755{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003756#ifdef UNION_WAIT
3757 union wait status;
3758#define status_i (status.w_status)
3759#else
3760 int status;
3761#define status_i status
3762#endif
3763 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003764
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003765 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003766 {
3767 return NULL;
3768 }
3769
3770 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003771#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003772}
3773#endif /* WSTOPSIG */
3774
3775#endif /* HAVE_SYS_WAIT_H */
3776
3777
Guido van Rossum94f6f721999-01-06 18:42:14 +00003778#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00003779#ifdef _SCO_DS
3780/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
3781 needed definitions in sys/statvfs.h */
3782#define _SVID3
3783#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003784#include <sys/statvfs.h>
3785
3786static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003787"fstatvfs(fd) -> \n\
3788 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00003789Perform an fstatvfs system call on the given fd.";
3790
3791static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003792posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00003793{
3794 int fd, res;
3795 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003796 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003797 return NULL;
3798 Py_BEGIN_ALLOW_THREADS
3799 res = fstatvfs(fd, &st);
3800 Py_END_ALLOW_THREADS
3801 if (res != 0)
3802 return posix_error();
3803#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003804 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003805 (long) st.f_bsize,
3806 (long) st.f_frsize,
3807 (long) st.f_blocks,
3808 (long) st.f_bfree,
3809 (long) st.f_bavail,
3810 (long) st.f_files,
3811 (long) st.f_ffree,
3812 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003813 (long) st.f_flag,
3814 (long) st.f_namemax);
3815#else
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003816 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003817 (long) st.f_bsize,
3818 (long) st.f_frsize,
3819 (LONG_LONG) st.f_blocks,
3820 (LONG_LONG) st.f_bfree,
3821 (LONG_LONG) st.f_bavail,
3822 (LONG_LONG) st.f_files,
3823 (LONG_LONG) st.f_ffree,
3824 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003825 (long) st.f_flag,
3826 (long) st.f_namemax);
3827#endif
3828}
3829#endif /* HAVE_FSTATVFS */
3830
3831
3832#if defined(HAVE_STATVFS)
3833#include <sys/statvfs.h>
3834
3835static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003836"statvfs(path) -> \n\
3837 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00003838Perform a statvfs system call on the given path.";
3839
3840static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003841posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00003842{
3843 char *path;
3844 int res;
3845 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003846 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003847 return NULL;
3848 Py_BEGIN_ALLOW_THREADS
3849 res = statvfs(path, &st);
3850 Py_END_ALLOW_THREADS
3851 if (res != 0)
3852 return posix_error_with_filename(path);
3853#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003854 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003855 (long) st.f_bsize,
3856 (long) st.f_frsize,
3857 (long) st.f_blocks,
3858 (long) st.f_bfree,
3859 (long) st.f_bavail,
3860 (long) st.f_files,
3861 (long) st.f_ffree,
3862 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003863 (long) st.f_flag,
3864 (long) st.f_namemax);
3865#else /* HAVE_LARGEFILE_SUPPORT */
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003866 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003867 (long) st.f_bsize,
3868 (long) st.f_frsize,
3869 (LONG_LONG) st.f_blocks,
3870 (LONG_LONG) st.f_bfree,
3871 (LONG_LONG) st.f_bavail,
3872 (LONG_LONG) st.f_files,
3873 (LONG_LONG) st.f_ffree,
3874 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003875 (long) st.f_flag,
3876 (long) st.f_namemax);
3877#endif
3878}
3879#endif /* HAVE_STATVFS */
3880
3881
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003882#ifdef HAVE_TEMPNAM
3883static char posix_tempnam__doc__[] = "\
3884tempnam([dir[, prefix]]) -> string\n\
3885Return a unique name for a temporary file.\n\
3886The directory and a short may be specified as strings; they may be omitted\n\
3887or None if not needed.";
3888
3889static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003890posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003891{
3892 PyObject *result = NULL;
3893 char *dir = NULL;
3894 char *pfx = NULL;
3895 char *name;
3896
3897 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
3898 return NULL;
3899 name = tempnam(dir, pfx);
3900 if (name == NULL)
3901 return PyErr_NoMemory();
3902 result = PyString_FromString(name);
3903 free(name);
3904 return result;
3905}
Guido van Rossumd371ff11999-01-25 16:12:23 +00003906#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003907
3908
3909#ifdef HAVE_TMPFILE
3910static char posix_tmpfile__doc__[] = "\
3911tmpfile() -> file object\n\
3912Create a temporary file with no directory entries.";
3913
3914static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003915posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003916{
3917 FILE *fp;
3918
3919 if (!PyArg_ParseTuple(args, ":tmpfile"))
3920 return NULL;
3921 fp = tmpfile();
3922 if (fp == NULL)
3923 return posix_error();
3924 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
3925}
3926#endif
3927
3928
3929#ifdef HAVE_TMPNAM
3930static char posix_tmpnam__doc__[] = "\
3931tmpnam() -> string\n\
3932Return a unique name for a temporary file.";
3933
3934static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003935posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003936{
3937 char buffer[L_tmpnam];
3938 char *name;
3939
3940 if (!PyArg_ParseTuple(args, ":tmpnam"))
3941 return NULL;
Greg Wardb48bc172000-03-01 21:51:56 +00003942#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003943 name = tmpnam_r(buffer);
3944#else
3945 name = tmpnam(buffer);
3946#endif
3947 if (name == NULL) {
3948 PyErr_SetObject(PyExc_OSError,
3949 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00003950#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003951 "unexpected NULL from tmpnam_r"
3952#else
3953 "unexpected NULL from tmpnam"
3954#endif
3955 ));
3956 return NULL;
3957 }
3958 return PyString_FromString(buffer);
3959}
3960#endif
3961
3962
Fred Drakec9680921999-12-13 16:37:25 +00003963/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
3964 * It maps strings representing configuration variable names to
3965 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00003966 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00003967 * rarely-used constants. There are three separate tables that use
3968 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00003969 *
3970 * This code is always included, even if none of the interfaces that
3971 * need it are included. The #if hackery needed to avoid it would be
3972 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00003973 */
3974struct constdef {
3975 char *name;
3976 long value;
3977};
3978
Fred Drake12c6e2d1999-12-14 21:25:03 +00003979static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003980conv_confname(PyObject *arg, int *valuep, struct constdef *table,
3981 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003982{
3983 if (PyInt_Check(arg)) {
3984 *valuep = PyInt_AS_LONG(arg);
3985 return 1;
3986 }
3987 if (PyString_Check(arg)) {
3988 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00003989 size_t lo = 0;
3990 size_t mid;
3991 size_t hi = tablesize;
3992 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003993 char *confname = PyString_AS_STRING(arg);
3994 while (lo < hi) {
3995 mid = (lo + hi) / 2;
3996 cmp = strcmp(confname, table[mid].name);
3997 if (cmp < 0)
3998 hi = mid;
3999 else if (cmp > 0)
4000 lo = mid + 1;
4001 else {
4002 *valuep = table[mid].value;
4003 return 1;
4004 }
4005 }
4006 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
4007 }
4008 else
4009 PyErr_SetString(PyExc_TypeError,
4010 "configuration names must be strings or integers");
4011 return 0;
4012}
4013
4014
4015#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4016static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004017#ifdef _PC_ABI_AIO_XFER_MAX
4018 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
4019#endif
4020#ifdef _PC_ABI_ASYNC_IO
4021 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
4022#endif
Fred Drakec9680921999-12-13 16:37:25 +00004023#ifdef _PC_ASYNC_IO
4024 {"PC_ASYNC_IO", _PC_ASYNC_IO},
4025#endif
4026#ifdef _PC_CHOWN_RESTRICTED
4027 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
4028#endif
4029#ifdef _PC_FILESIZEBITS
4030 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
4031#endif
4032#ifdef _PC_LAST
4033 {"PC_LAST", _PC_LAST},
4034#endif
4035#ifdef _PC_LINK_MAX
4036 {"PC_LINK_MAX", _PC_LINK_MAX},
4037#endif
4038#ifdef _PC_MAX_CANON
4039 {"PC_MAX_CANON", _PC_MAX_CANON},
4040#endif
4041#ifdef _PC_MAX_INPUT
4042 {"PC_MAX_INPUT", _PC_MAX_INPUT},
4043#endif
4044#ifdef _PC_NAME_MAX
4045 {"PC_NAME_MAX", _PC_NAME_MAX},
4046#endif
4047#ifdef _PC_NO_TRUNC
4048 {"PC_NO_TRUNC", _PC_NO_TRUNC},
4049#endif
4050#ifdef _PC_PATH_MAX
4051 {"PC_PATH_MAX", _PC_PATH_MAX},
4052#endif
4053#ifdef _PC_PIPE_BUF
4054 {"PC_PIPE_BUF", _PC_PIPE_BUF},
4055#endif
4056#ifdef _PC_PRIO_IO
4057 {"PC_PRIO_IO", _PC_PRIO_IO},
4058#endif
4059#ifdef _PC_SOCK_MAXBUF
4060 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
4061#endif
4062#ifdef _PC_SYNC_IO
4063 {"PC_SYNC_IO", _PC_SYNC_IO},
4064#endif
4065#ifdef _PC_VDISABLE
4066 {"PC_VDISABLE", _PC_VDISABLE},
4067#endif
4068};
4069
Fred Drakec9680921999-12-13 16:37:25 +00004070static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004071conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004072{
4073 return conv_confname(arg, valuep, posix_constants_pathconf,
4074 sizeof(posix_constants_pathconf)
4075 / sizeof(struct constdef));
4076}
4077#endif
4078
4079#ifdef HAVE_FPATHCONF
4080static char posix_fpathconf__doc__[] = "\
4081fpathconf(fd, name) -> integer\n\
4082Return the configuration limit name for the file descriptor fd.\n\
4083If there is no limit, return -1.";
4084
4085static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004086posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004087{
4088 PyObject *result = NULL;
4089 int name, fd;
4090
Fred Drake12c6e2d1999-12-14 21:25:03 +00004091 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4092 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00004093 long limit;
4094
4095 errno = 0;
4096 limit = fpathconf(fd, name);
4097 if (limit == -1 && errno != 0)
4098 posix_error();
4099 else
4100 result = PyInt_FromLong(limit);
4101 }
4102 return result;
4103}
4104#endif
4105
4106
4107#ifdef HAVE_PATHCONF
4108static char posix_pathconf__doc__[] = "\
4109pathconf(path, name) -> integer\n\
4110Return the configuration limit name for the file or directory path.\n\
4111If there is no limit, return -1.";
4112
4113static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004114posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004115{
4116 PyObject *result = NULL;
4117 int name;
4118 char *path;
4119
4120 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4121 conv_path_confname, &name)) {
4122 long limit;
4123
4124 errno = 0;
4125 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004126 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00004127 if (errno == EINVAL)
4128 /* could be a path or name problem */
4129 posix_error();
4130 else
4131 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004132 }
Fred Drakec9680921999-12-13 16:37:25 +00004133 else
4134 result = PyInt_FromLong(limit);
4135 }
4136 return result;
4137}
4138#endif
4139
4140#ifdef HAVE_CONFSTR
4141static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004142#ifdef _CS_ARCHITECTURE
4143 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4144#endif
4145#ifdef _CS_HOSTNAME
4146 {"CS_HOSTNAME", _CS_HOSTNAME},
4147#endif
4148#ifdef _CS_HW_PROVIDER
4149 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4150#endif
4151#ifdef _CS_HW_SERIAL
4152 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4153#endif
4154#ifdef _CS_INITTAB_NAME
4155 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4156#endif
Fred Drakec9680921999-12-13 16:37:25 +00004157#ifdef _CS_LFS64_CFLAGS
4158 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4159#endif
4160#ifdef _CS_LFS64_LDFLAGS
4161 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4162#endif
4163#ifdef _CS_LFS64_LIBS
4164 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4165#endif
4166#ifdef _CS_LFS64_LINTFLAGS
4167 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4168#endif
4169#ifdef _CS_LFS_CFLAGS
4170 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4171#endif
4172#ifdef _CS_LFS_LDFLAGS
4173 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4174#endif
4175#ifdef _CS_LFS_LIBS
4176 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4177#endif
4178#ifdef _CS_LFS_LINTFLAGS
4179 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4180#endif
Fred Draked86ed291999-12-15 15:34:33 +00004181#ifdef _CS_MACHINE
4182 {"CS_MACHINE", _CS_MACHINE},
4183#endif
Fred Drakec9680921999-12-13 16:37:25 +00004184#ifdef _CS_PATH
4185 {"CS_PATH", _CS_PATH},
4186#endif
Fred Draked86ed291999-12-15 15:34:33 +00004187#ifdef _CS_RELEASE
4188 {"CS_RELEASE", _CS_RELEASE},
4189#endif
4190#ifdef _CS_SRPC_DOMAIN
4191 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4192#endif
4193#ifdef _CS_SYSNAME
4194 {"CS_SYSNAME", _CS_SYSNAME},
4195#endif
4196#ifdef _CS_VERSION
4197 {"CS_VERSION", _CS_VERSION},
4198#endif
Fred Drakec9680921999-12-13 16:37:25 +00004199#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4200 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4201#endif
4202#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4203 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4204#endif
4205#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4206 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4207#endif
4208#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4209 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4210#endif
4211#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4212 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4213#endif
4214#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4215 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4216#endif
4217#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4218 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4219#endif
4220#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4221 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4222#endif
4223#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4224 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4225#endif
4226#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4227 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4228#endif
4229#ifdef _CS_XBS5_LP64_OFF64_LIBS
4230 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4231#endif
4232#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4233 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4234#endif
4235#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4236 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4237#endif
4238#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4239 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4240#endif
4241#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4242 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4243#endif
4244#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4245 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4246#endif
Fred Draked86ed291999-12-15 15:34:33 +00004247#ifdef _MIPS_CS_AVAIL_PROCESSORS
4248 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4249#endif
4250#ifdef _MIPS_CS_BASE
4251 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4252#endif
4253#ifdef _MIPS_CS_HOSTID
4254 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4255#endif
4256#ifdef _MIPS_CS_HW_NAME
4257 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4258#endif
4259#ifdef _MIPS_CS_NUM_PROCESSORS
4260 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4261#endif
4262#ifdef _MIPS_CS_OSREL_MAJ
4263 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4264#endif
4265#ifdef _MIPS_CS_OSREL_MIN
4266 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4267#endif
4268#ifdef _MIPS_CS_OSREL_PATCH
4269 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4270#endif
4271#ifdef _MIPS_CS_OS_NAME
4272 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4273#endif
4274#ifdef _MIPS_CS_OS_PROVIDER
4275 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4276#endif
4277#ifdef _MIPS_CS_PROCESSORS
4278 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4279#endif
4280#ifdef _MIPS_CS_SERIAL
4281 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4282#endif
4283#ifdef _MIPS_CS_VENDOR
4284 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4285#endif
Fred Drakec9680921999-12-13 16:37:25 +00004286};
4287
4288static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004289conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004290{
4291 return conv_confname(arg, valuep, posix_constants_confstr,
4292 sizeof(posix_constants_confstr)
4293 / sizeof(struct constdef));
4294}
4295
4296static char posix_confstr__doc__[] = "\
4297confstr(name) -> string\n\
4298Return a string-valued system configuration variable.";
4299
4300static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004301posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004302{
4303 PyObject *result = NULL;
4304 int name;
4305 char buffer[64];
4306
4307 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4308 int len = confstr(name, buffer, sizeof(buffer));
4309
Fred Drakec9680921999-12-13 16:37:25 +00004310 errno = 0;
4311 if (len == 0) {
4312 if (errno != 0)
4313 posix_error();
4314 else
4315 result = PyString_FromString("");
4316 }
4317 else {
4318 if (len >= sizeof(buffer)) {
4319 result = PyString_FromStringAndSize(NULL, len);
4320 if (result != NULL)
4321 confstr(name, PyString_AS_STRING(result), len+1);
4322 }
4323 else
4324 result = PyString_FromString(buffer);
4325 }
4326 }
4327 return result;
4328}
4329#endif
4330
4331
4332#ifdef HAVE_SYSCONF
4333static struct constdef posix_constants_sysconf[] = {
4334#ifdef _SC_2_CHAR_TERM
4335 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4336#endif
4337#ifdef _SC_2_C_BIND
4338 {"SC_2_C_BIND", _SC_2_C_BIND},
4339#endif
4340#ifdef _SC_2_C_DEV
4341 {"SC_2_C_DEV", _SC_2_C_DEV},
4342#endif
4343#ifdef _SC_2_C_VERSION
4344 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4345#endif
4346#ifdef _SC_2_FORT_DEV
4347 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4348#endif
4349#ifdef _SC_2_FORT_RUN
4350 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4351#endif
4352#ifdef _SC_2_LOCALEDEF
4353 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4354#endif
4355#ifdef _SC_2_SW_DEV
4356 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4357#endif
4358#ifdef _SC_2_UPE
4359 {"SC_2_UPE", _SC_2_UPE},
4360#endif
4361#ifdef _SC_2_VERSION
4362 {"SC_2_VERSION", _SC_2_VERSION},
4363#endif
Fred Draked86ed291999-12-15 15:34:33 +00004364#ifdef _SC_ABI_ASYNCHRONOUS_IO
4365 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4366#endif
4367#ifdef _SC_ACL
4368 {"SC_ACL", _SC_ACL},
4369#endif
Fred Drakec9680921999-12-13 16:37:25 +00004370#ifdef _SC_AIO_LISTIO_MAX
4371 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4372#endif
Fred Drakec9680921999-12-13 16:37:25 +00004373#ifdef _SC_AIO_MAX
4374 {"SC_AIO_MAX", _SC_AIO_MAX},
4375#endif
4376#ifdef _SC_AIO_PRIO_DELTA_MAX
4377 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4378#endif
4379#ifdef _SC_ARG_MAX
4380 {"SC_ARG_MAX", _SC_ARG_MAX},
4381#endif
4382#ifdef _SC_ASYNCHRONOUS_IO
4383 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4384#endif
4385#ifdef _SC_ATEXIT_MAX
4386 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4387#endif
Fred Draked86ed291999-12-15 15:34:33 +00004388#ifdef _SC_AUDIT
4389 {"SC_AUDIT", _SC_AUDIT},
4390#endif
Fred Drakec9680921999-12-13 16:37:25 +00004391#ifdef _SC_AVPHYS_PAGES
4392 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4393#endif
4394#ifdef _SC_BC_BASE_MAX
4395 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4396#endif
4397#ifdef _SC_BC_DIM_MAX
4398 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4399#endif
4400#ifdef _SC_BC_SCALE_MAX
4401 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4402#endif
4403#ifdef _SC_BC_STRING_MAX
4404 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4405#endif
Fred Draked86ed291999-12-15 15:34:33 +00004406#ifdef _SC_CAP
4407 {"SC_CAP", _SC_CAP},
4408#endif
Fred Drakec9680921999-12-13 16:37:25 +00004409#ifdef _SC_CHARCLASS_NAME_MAX
4410 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4411#endif
4412#ifdef _SC_CHAR_BIT
4413 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4414#endif
4415#ifdef _SC_CHAR_MAX
4416 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4417#endif
4418#ifdef _SC_CHAR_MIN
4419 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4420#endif
4421#ifdef _SC_CHILD_MAX
4422 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4423#endif
4424#ifdef _SC_CLK_TCK
4425 {"SC_CLK_TCK", _SC_CLK_TCK},
4426#endif
4427#ifdef _SC_COHER_BLKSZ
4428 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4429#endif
4430#ifdef _SC_COLL_WEIGHTS_MAX
4431 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4432#endif
4433#ifdef _SC_DCACHE_ASSOC
4434 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4435#endif
4436#ifdef _SC_DCACHE_BLKSZ
4437 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4438#endif
4439#ifdef _SC_DCACHE_LINESZ
4440 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4441#endif
4442#ifdef _SC_DCACHE_SZ
4443 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
4444#endif
4445#ifdef _SC_DCACHE_TBLKSZ
4446 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
4447#endif
4448#ifdef _SC_DELAYTIMER_MAX
4449 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
4450#endif
4451#ifdef _SC_EQUIV_CLASS_MAX
4452 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
4453#endif
4454#ifdef _SC_EXPR_NEST_MAX
4455 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
4456#endif
4457#ifdef _SC_FSYNC
4458 {"SC_FSYNC", _SC_FSYNC},
4459#endif
4460#ifdef _SC_GETGR_R_SIZE_MAX
4461 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
4462#endif
4463#ifdef _SC_GETPW_R_SIZE_MAX
4464 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
4465#endif
4466#ifdef _SC_ICACHE_ASSOC
4467 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
4468#endif
4469#ifdef _SC_ICACHE_BLKSZ
4470 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
4471#endif
4472#ifdef _SC_ICACHE_LINESZ
4473 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
4474#endif
4475#ifdef _SC_ICACHE_SZ
4476 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
4477#endif
Fred Draked86ed291999-12-15 15:34:33 +00004478#ifdef _SC_INF
4479 {"SC_INF", _SC_INF},
4480#endif
Fred Drakec9680921999-12-13 16:37:25 +00004481#ifdef _SC_INT_MAX
4482 {"SC_INT_MAX", _SC_INT_MAX},
4483#endif
4484#ifdef _SC_INT_MIN
4485 {"SC_INT_MIN", _SC_INT_MIN},
4486#endif
4487#ifdef _SC_IOV_MAX
4488 {"SC_IOV_MAX", _SC_IOV_MAX},
4489#endif
Fred Draked86ed291999-12-15 15:34:33 +00004490#ifdef _SC_IP_SECOPTS
4491 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
4492#endif
Fred Drakec9680921999-12-13 16:37:25 +00004493#ifdef _SC_JOB_CONTROL
4494 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
4495#endif
Fred Draked86ed291999-12-15 15:34:33 +00004496#ifdef _SC_KERN_POINTERS
4497 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
4498#endif
4499#ifdef _SC_KERN_SIM
4500 {"SC_KERN_SIM", _SC_KERN_SIM},
4501#endif
Fred Drakec9680921999-12-13 16:37:25 +00004502#ifdef _SC_LINE_MAX
4503 {"SC_LINE_MAX", _SC_LINE_MAX},
4504#endif
4505#ifdef _SC_LOGIN_NAME_MAX
4506 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
4507#endif
4508#ifdef _SC_LOGNAME_MAX
4509 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
4510#endif
4511#ifdef _SC_LONG_BIT
4512 {"SC_LONG_BIT", _SC_LONG_BIT},
4513#endif
Fred Draked86ed291999-12-15 15:34:33 +00004514#ifdef _SC_MAC
4515 {"SC_MAC", _SC_MAC},
4516#endif
Fred Drakec9680921999-12-13 16:37:25 +00004517#ifdef _SC_MAPPED_FILES
4518 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
4519#endif
4520#ifdef _SC_MAXPID
4521 {"SC_MAXPID", _SC_MAXPID},
4522#endif
4523#ifdef _SC_MB_LEN_MAX
4524 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
4525#endif
4526#ifdef _SC_MEMLOCK
4527 {"SC_MEMLOCK", _SC_MEMLOCK},
4528#endif
4529#ifdef _SC_MEMLOCK_RANGE
4530 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
4531#endif
4532#ifdef _SC_MEMORY_PROTECTION
4533 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
4534#endif
4535#ifdef _SC_MESSAGE_PASSING
4536 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
4537#endif
Fred Draked86ed291999-12-15 15:34:33 +00004538#ifdef _SC_MMAP_FIXED_ALIGNMENT
4539 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
4540#endif
Fred Drakec9680921999-12-13 16:37:25 +00004541#ifdef _SC_MQ_OPEN_MAX
4542 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
4543#endif
4544#ifdef _SC_MQ_PRIO_MAX
4545 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
4546#endif
Fred Draked86ed291999-12-15 15:34:33 +00004547#ifdef _SC_NACLS_MAX
4548 {"SC_NACLS_MAX", _SC_NACLS_MAX},
4549#endif
Fred Drakec9680921999-12-13 16:37:25 +00004550#ifdef _SC_NGROUPS_MAX
4551 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
4552#endif
4553#ifdef _SC_NL_ARGMAX
4554 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
4555#endif
4556#ifdef _SC_NL_LANGMAX
4557 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
4558#endif
4559#ifdef _SC_NL_MSGMAX
4560 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
4561#endif
4562#ifdef _SC_NL_NMAX
4563 {"SC_NL_NMAX", _SC_NL_NMAX},
4564#endif
4565#ifdef _SC_NL_SETMAX
4566 {"SC_NL_SETMAX", _SC_NL_SETMAX},
4567#endif
4568#ifdef _SC_NL_TEXTMAX
4569 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
4570#endif
4571#ifdef _SC_NPROCESSORS_CONF
4572 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
4573#endif
4574#ifdef _SC_NPROCESSORS_ONLN
4575 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
4576#endif
Fred Draked86ed291999-12-15 15:34:33 +00004577#ifdef _SC_NPROC_CONF
4578 {"SC_NPROC_CONF", _SC_NPROC_CONF},
4579#endif
4580#ifdef _SC_NPROC_ONLN
4581 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
4582#endif
Fred Drakec9680921999-12-13 16:37:25 +00004583#ifdef _SC_NZERO
4584 {"SC_NZERO", _SC_NZERO},
4585#endif
4586#ifdef _SC_OPEN_MAX
4587 {"SC_OPEN_MAX", _SC_OPEN_MAX},
4588#endif
4589#ifdef _SC_PAGESIZE
4590 {"SC_PAGESIZE", _SC_PAGESIZE},
4591#endif
4592#ifdef _SC_PAGE_SIZE
4593 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
4594#endif
4595#ifdef _SC_PASS_MAX
4596 {"SC_PASS_MAX", _SC_PASS_MAX},
4597#endif
4598#ifdef _SC_PHYS_PAGES
4599 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
4600#endif
4601#ifdef _SC_PII
4602 {"SC_PII", _SC_PII},
4603#endif
4604#ifdef _SC_PII_INTERNET
4605 {"SC_PII_INTERNET", _SC_PII_INTERNET},
4606#endif
4607#ifdef _SC_PII_INTERNET_DGRAM
4608 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
4609#endif
4610#ifdef _SC_PII_INTERNET_STREAM
4611 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
4612#endif
4613#ifdef _SC_PII_OSI
4614 {"SC_PII_OSI", _SC_PII_OSI},
4615#endif
4616#ifdef _SC_PII_OSI_CLTS
4617 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
4618#endif
4619#ifdef _SC_PII_OSI_COTS
4620 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
4621#endif
4622#ifdef _SC_PII_OSI_M
4623 {"SC_PII_OSI_M", _SC_PII_OSI_M},
4624#endif
4625#ifdef _SC_PII_SOCKET
4626 {"SC_PII_SOCKET", _SC_PII_SOCKET},
4627#endif
4628#ifdef _SC_PII_XTI
4629 {"SC_PII_XTI", _SC_PII_XTI},
4630#endif
4631#ifdef _SC_POLL
4632 {"SC_POLL", _SC_POLL},
4633#endif
4634#ifdef _SC_PRIORITIZED_IO
4635 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
4636#endif
4637#ifdef _SC_PRIORITY_SCHEDULING
4638 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
4639#endif
4640#ifdef _SC_REALTIME_SIGNALS
4641 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
4642#endif
4643#ifdef _SC_RE_DUP_MAX
4644 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
4645#endif
4646#ifdef _SC_RTSIG_MAX
4647 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
4648#endif
4649#ifdef _SC_SAVED_IDS
4650 {"SC_SAVED_IDS", _SC_SAVED_IDS},
4651#endif
4652#ifdef _SC_SCHAR_MAX
4653 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
4654#endif
4655#ifdef _SC_SCHAR_MIN
4656 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
4657#endif
4658#ifdef _SC_SELECT
4659 {"SC_SELECT", _SC_SELECT},
4660#endif
4661#ifdef _SC_SEMAPHORES
4662 {"SC_SEMAPHORES", _SC_SEMAPHORES},
4663#endif
4664#ifdef _SC_SEM_NSEMS_MAX
4665 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
4666#endif
4667#ifdef _SC_SEM_VALUE_MAX
4668 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
4669#endif
4670#ifdef _SC_SHARED_MEMORY_OBJECTS
4671 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
4672#endif
4673#ifdef _SC_SHRT_MAX
4674 {"SC_SHRT_MAX", _SC_SHRT_MAX},
4675#endif
4676#ifdef _SC_SHRT_MIN
4677 {"SC_SHRT_MIN", _SC_SHRT_MIN},
4678#endif
4679#ifdef _SC_SIGQUEUE_MAX
4680 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
4681#endif
4682#ifdef _SC_SIGRT_MAX
4683 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
4684#endif
4685#ifdef _SC_SIGRT_MIN
4686 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
4687#endif
Fred Draked86ed291999-12-15 15:34:33 +00004688#ifdef _SC_SOFTPOWER
4689 {"SC_SOFTPOWER", _SC_SOFTPOWER},
4690#endif
Fred Drakec9680921999-12-13 16:37:25 +00004691#ifdef _SC_SPLIT_CACHE
4692 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
4693#endif
4694#ifdef _SC_SSIZE_MAX
4695 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
4696#endif
4697#ifdef _SC_STACK_PROT
4698 {"SC_STACK_PROT", _SC_STACK_PROT},
4699#endif
4700#ifdef _SC_STREAM_MAX
4701 {"SC_STREAM_MAX", _SC_STREAM_MAX},
4702#endif
4703#ifdef _SC_SYNCHRONIZED_IO
4704 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
4705#endif
4706#ifdef _SC_THREADS
4707 {"SC_THREADS", _SC_THREADS},
4708#endif
4709#ifdef _SC_THREAD_ATTR_STACKADDR
4710 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
4711#endif
4712#ifdef _SC_THREAD_ATTR_STACKSIZE
4713 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
4714#endif
4715#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
4716 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
4717#endif
4718#ifdef _SC_THREAD_KEYS_MAX
4719 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
4720#endif
4721#ifdef _SC_THREAD_PRIORITY_SCHEDULING
4722 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
4723#endif
4724#ifdef _SC_THREAD_PRIO_INHERIT
4725 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
4726#endif
4727#ifdef _SC_THREAD_PRIO_PROTECT
4728 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
4729#endif
4730#ifdef _SC_THREAD_PROCESS_SHARED
4731 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
4732#endif
4733#ifdef _SC_THREAD_SAFE_FUNCTIONS
4734 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
4735#endif
4736#ifdef _SC_THREAD_STACK_MIN
4737 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
4738#endif
4739#ifdef _SC_THREAD_THREADS_MAX
4740 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
4741#endif
4742#ifdef _SC_TIMERS
4743 {"SC_TIMERS", _SC_TIMERS},
4744#endif
4745#ifdef _SC_TIMER_MAX
4746 {"SC_TIMER_MAX", _SC_TIMER_MAX},
4747#endif
4748#ifdef _SC_TTY_NAME_MAX
4749 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
4750#endif
4751#ifdef _SC_TZNAME_MAX
4752 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
4753#endif
4754#ifdef _SC_T_IOV_MAX
4755 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
4756#endif
4757#ifdef _SC_UCHAR_MAX
4758 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
4759#endif
4760#ifdef _SC_UINT_MAX
4761 {"SC_UINT_MAX", _SC_UINT_MAX},
4762#endif
4763#ifdef _SC_UIO_MAXIOV
4764 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
4765#endif
4766#ifdef _SC_ULONG_MAX
4767 {"SC_ULONG_MAX", _SC_ULONG_MAX},
4768#endif
4769#ifdef _SC_USHRT_MAX
4770 {"SC_USHRT_MAX", _SC_USHRT_MAX},
4771#endif
4772#ifdef _SC_VERSION
4773 {"SC_VERSION", _SC_VERSION},
4774#endif
4775#ifdef _SC_WORD_BIT
4776 {"SC_WORD_BIT", _SC_WORD_BIT},
4777#endif
4778#ifdef _SC_XBS5_ILP32_OFF32
4779 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
4780#endif
4781#ifdef _SC_XBS5_ILP32_OFFBIG
4782 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
4783#endif
4784#ifdef _SC_XBS5_LP64_OFF64
4785 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
4786#endif
4787#ifdef _SC_XBS5_LPBIG_OFFBIG
4788 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
4789#endif
4790#ifdef _SC_XOPEN_CRYPT
4791 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
4792#endif
4793#ifdef _SC_XOPEN_ENH_I18N
4794 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
4795#endif
4796#ifdef _SC_XOPEN_LEGACY
4797 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
4798#endif
4799#ifdef _SC_XOPEN_REALTIME
4800 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
4801#endif
4802#ifdef _SC_XOPEN_REALTIME_THREADS
4803 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
4804#endif
4805#ifdef _SC_XOPEN_SHM
4806 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
4807#endif
4808#ifdef _SC_XOPEN_UNIX
4809 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
4810#endif
4811#ifdef _SC_XOPEN_VERSION
4812 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
4813#endif
4814#ifdef _SC_XOPEN_XCU_VERSION
4815 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
4816#endif
4817#ifdef _SC_XOPEN_XPG2
4818 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
4819#endif
4820#ifdef _SC_XOPEN_XPG3
4821 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
4822#endif
4823#ifdef _SC_XOPEN_XPG4
4824 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
4825#endif
4826};
4827
4828static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004829conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004830{
4831 return conv_confname(arg, valuep, posix_constants_sysconf,
4832 sizeof(posix_constants_sysconf)
4833 / sizeof(struct constdef));
4834}
4835
4836static char posix_sysconf__doc__[] = "\
4837sysconf(name) -> integer\n\
4838Return an integer-valued system configuration variable.";
4839
4840static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004841posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004842{
4843 PyObject *result = NULL;
4844 int name;
4845
4846 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
4847 int value;
4848
4849 errno = 0;
4850 value = sysconf(name);
4851 if (value == -1 && errno != 0)
4852 posix_error();
4853 else
4854 result = PyInt_FromLong(value);
4855 }
4856 return result;
4857}
4858#endif
4859
4860
Fred Drakebec628d1999-12-15 18:31:10 +00004861/* This code is used to ensure that the tables of configuration value names
4862 * are in sorted order as required by conv_confname(), and also to build the
4863 * the exported dictionaries that are used to publish information about the
4864 * names available on the host platform.
4865 *
4866 * Sorting the table at runtime ensures that the table is properly ordered
4867 * when used, even for platforms we're not able to test on. It also makes
4868 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00004869 */
Fred Drakebec628d1999-12-15 18:31:10 +00004870
4871static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004872cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00004873{
4874 const struct constdef *c1 =
4875 (const struct constdef *) v1;
4876 const struct constdef *c2 =
4877 (const struct constdef *) v2;
4878
4879 return strcmp(c1->name, c2->name);
4880}
4881
4882static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004883setup_confname_table(struct constdef *table, size_t tablesize,
4884 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00004885{
Fred Drakebec628d1999-12-15 18:31:10 +00004886 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00004887 size_t i;
4888 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00004889
4890 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
4891 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00004892 if (d == NULL)
4893 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004894
Barry Warsaw3155db32000-04-13 15:20:40 +00004895 for (i=0; i < tablesize; ++i) {
4896 PyObject *o = PyInt_FromLong(table[i].value);
4897 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
4898 Py_XDECREF(o);
4899 Py_DECREF(d);
4900 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004901 }
Barry Warsaw3155db32000-04-13 15:20:40 +00004902 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00004903 }
Barry Warsaw3155db32000-04-13 15:20:40 +00004904 status = PyDict_SetItemString(moddict, tablename, d);
4905 Py_DECREF(d);
4906 return status;
Fred Draked86ed291999-12-15 15:34:33 +00004907}
4908
Fred Drakebec628d1999-12-15 18:31:10 +00004909/* Return -1 on failure, 0 on success. */
4910static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004911setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00004912{
4913#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00004914 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00004915 sizeof(posix_constants_pathconf)
4916 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00004917 "pathconf_names", moddict))
4918 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004919#endif
4920#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00004921 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00004922 sizeof(posix_constants_confstr)
4923 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00004924 "confstr_names", moddict))
4925 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004926#endif
4927#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00004928 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00004929 sizeof(posix_constants_sysconf)
4930 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00004931 "sysconf_names", moddict))
4932 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004933#endif
Fred Drakebec628d1999-12-15 18:31:10 +00004934 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00004935}
Fred Draked86ed291999-12-15 15:34:33 +00004936
4937
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004938static char posix_abort__doc__[] = "\
4939abort() -> does not return!\n\
4940Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
4941in the hardest way possible on the hosting operating system.";
4942
4943static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004944posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004945{
4946 if (!PyArg_ParseTuple(args, ":abort"))
4947 return NULL;
4948 abort();
4949 /*NOTREACHED*/
4950 Py_FatalError("abort() called from Python code didn't abort!");
4951 return NULL;
4952}
Fred Drakebec628d1999-12-15 18:31:10 +00004953
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004954
4955static PyMethodDef posix_methods[] = {
4956 {"access", posix_access, METH_VARARGS, posix_access__doc__},
4957#ifdef HAVE_TTYNAME
4958 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
4959#endif
4960 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
4961 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004962#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004963 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004964#endif /* HAVE_CHOWN */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004965#ifdef HAVE_CTERMID
4966 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
4967#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00004968#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004969 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00004970#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004971#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004972 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004973#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004974 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
4975 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
4976 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004977#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004978 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004979#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004980#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004981 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004982#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004983 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
4984 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
4985 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004986#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004987 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004988#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004989#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004990 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004991#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004992 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004993#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004994 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004995#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004996 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
4997 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
4998 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004999#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005000 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005001#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005002 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005003#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005004 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5005 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005006#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00005007#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005008 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5009 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00005010#endif /* HAVE_SPAWNV */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005011#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005012 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005013#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005014#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005015 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00005016#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005017#ifdef HAVE_FORKPTY
5018 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5019#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005020#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005021 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005022#endif /* HAVE_GETEGID */
5023#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005024 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005025#endif /* HAVE_GETEUID */
5026#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005027 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005028#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00005029#ifdef HAVE_GETGROUPS
5030 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5031#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005032 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005033#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005034 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005035#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005036#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005037 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005038#endif /* HAVE_GETPPID */
5039#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005040 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005041#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005042#ifdef HAVE_GETLOGIN
5043 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5044#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00005045#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005046 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005047#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00005048#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005049 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00005050#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005051#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005052 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005053#ifdef MS_WIN32
5054 {"popen2", win32_popen2, METH_VARARGS},
5055 {"popen3", win32_popen3, METH_VARARGS},
5056 {"popen4", win32_popen4, METH_VARARGS},
5057#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005058#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005059#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005060 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005061#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005062#ifdef HAVE_SETEUID
5063 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5064#endif /* HAVE_SETEUID */
5065#ifdef HAVE_SETEGID
5066 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5067#endif /* HAVE_SETEGID */
5068#ifdef HAVE_SETREUID
5069 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5070#endif /* HAVE_SETREUID */
5071#ifdef HAVE_SETREGID
5072 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5073#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005074#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005075 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005076#endif /* HAVE_SETGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005077#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005078 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005079#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005080#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005081 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005082#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005083#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005084 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005085#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005086#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005087 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005088#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005089#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005090 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005091#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005092#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005093 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005094#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005095#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005096 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005097#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005098 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5099 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5100 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5101 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5102 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5103 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5104 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5105 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5106 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00005107 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005108#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005109 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005110#endif
5111#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005112 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005113#endif
5114#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005115 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005116#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005117#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005118 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005119#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00005120#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005121 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00005122#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00005123#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005124 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005125#endif
5126#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005127 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005128#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00005129#ifdef HAVE_SYS_WAIT_H
5130#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005131 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005132#endif /* WIFSTOPPED */
5133#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005134 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005135#endif /* WIFSIGNALED */
5136#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005137 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005138#endif /* WIFEXITED */
5139#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005140 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005141#endif /* WEXITSTATUS */
5142#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005143 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005144#endif /* WTERMSIG */
5145#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005146 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005147#endif /* WSTOPSIG */
5148#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005149#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005150 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005151#endif
5152#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005153 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005154#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005155#ifdef HAVE_TMPNAM
5156 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5157#endif
5158#ifdef HAVE_TEMPNAM
5159 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5160#endif
5161#ifdef HAVE_TMPNAM
5162 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5163#endif
Fred Drakec9680921999-12-13 16:37:25 +00005164#ifdef HAVE_CONFSTR
5165 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5166#endif
5167#ifdef HAVE_SYSCONF
5168 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5169#endif
5170#ifdef HAVE_FPATHCONF
5171 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5172#endif
5173#ifdef HAVE_PATHCONF
5174 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5175#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005176 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005177 {NULL, NULL} /* Sentinel */
5178};
5179
5180
Barry Warsaw4a342091996-12-19 23:50:02 +00005181static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005182ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005183{
5184 PyObject* v = PyInt_FromLong(value);
5185 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5186 return -1; /* triggers fatal error */
5187
5188 Py_DECREF(v);
5189 return 0;
5190}
5191
Guido van Rossumd48f2521997-12-05 22:19:34 +00005192#if defined(PYOS_OS2)
5193/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5194static int insertvalues(PyObject *d)
5195{
5196 APIRET rc;
5197 ULONG values[QSV_MAX+1];
5198 PyObject *v;
5199 char *ver, tmp[10];
5200
5201 Py_BEGIN_ALLOW_THREADS
5202 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5203 Py_END_ALLOW_THREADS
5204
5205 if (rc != NO_ERROR) {
5206 os2_error(rc);
5207 return -1;
5208 }
5209
5210 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5211 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5212 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5213 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5214 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5215 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5216 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5217
5218 switch (values[QSV_VERSION_MINOR]) {
5219 case 0: ver = "2.00"; break;
5220 case 10: ver = "2.10"; break;
5221 case 11: ver = "2.11"; break;
5222 case 30: ver = "3.00"; break;
5223 case 40: ver = "4.00"; break;
5224 case 50: ver = "5.00"; break;
5225 default:
5226 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
5227 values[QSV_VERSION_MINOR]);
5228 ver = &tmp[0];
5229 }
5230
5231 /* Add Indicator of the Version of the Operating System */
5232 v = PyString_FromString(ver);
5233 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5234 return -1;
5235 Py_DECREF(v);
5236
5237 /* Add Indicator of Which Drive was Used to Boot the System */
5238 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5239 tmp[1] = ':';
5240 tmp[2] = '\0';
5241
5242 v = PyString_FromString(tmp);
5243 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5244 return -1;
5245 Py_DECREF(v);
5246
5247 return 0;
5248}
5249#endif
5250
Barry Warsaw4a342091996-12-19 23:50:02 +00005251static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005252all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00005253{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005254#ifdef F_OK
5255 if (ins(d, "F_OK", (long)F_OK)) return -1;
5256#endif
5257#ifdef R_OK
5258 if (ins(d, "R_OK", (long)R_OK)) return -1;
5259#endif
5260#ifdef W_OK
5261 if (ins(d, "W_OK", (long)W_OK)) return -1;
5262#endif
5263#ifdef X_OK
5264 if (ins(d, "X_OK", (long)X_OK)) return -1;
5265#endif
Fred Drakec9680921999-12-13 16:37:25 +00005266#ifdef NGROUPS_MAX
5267 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5268#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005269#ifdef TMP_MAX
5270 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5271#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005272#ifdef WNOHANG
5273 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5274#endif
5275#ifdef O_RDONLY
5276 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5277#endif
5278#ifdef O_WRONLY
5279 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5280#endif
5281#ifdef O_RDWR
5282 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5283#endif
5284#ifdef O_NDELAY
5285 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5286#endif
5287#ifdef O_NONBLOCK
5288 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5289#endif
5290#ifdef O_APPEND
5291 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5292#endif
5293#ifdef O_DSYNC
5294 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5295#endif
5296#ifdef O_RSYNC
5297 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5298#endif
5299#ifdef O_SYNC
5300 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5301#endif
5302#ifdef O_NOCTTY
5303 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5304#endif
5305#ifdef O_CREAT
5306 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5307#endif
5308#ifdef O_EXCL
5309 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5310#endif
5311#ifdef O_TRUNC
5312 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5313#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005314#ifdef O_BINARY
5315 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5316#endif
5317#ifdef O_TEXT
5318 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5319#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005320
Guido van Rossum246bc171999-02-01 23:54:31 +00005321#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005322 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5323 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5324 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5325 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5326 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005327#endif
5328
Guido van Rossumd48f2521997-12-05 22:19:34 +00005329#if defined(PYOS_OS2)
5330 if (insertvalues(d)) return -1;
5331#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005332 return 0;
5333}
5334
5335
Guido van Rossumc5a0f531997-12-02 20:36:02 +00005336#if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005337#define INITFUNC initnt
5338#define MODNAME "nt"
5339#else
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005340#if defined(PYOS_OS2)
5341#define INITFUNC initos2
5342#define MODNAME "os2"
5343#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005344#define INITFUNC initposix
5345#define MODNAME "posix"
5346#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005347#endif
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005348
Guido van Rossum3886bb61998-12-04 18:50:17 +00005349DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005350INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00005351{
Barry Warsaw53699e91996-12-10 23:23:01 +00005352 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005353
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005354 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005355 posix_methods,
5356 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005357 (PyObject *)NULL,
5358 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005359 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005360
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005361 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005362 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005363 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005364 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005365 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005366
Barry Warsaw4a342091996-12-19 23:50:02 +00005367 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005368 return;
5369
Fred Drakebec628d1999-12-15 18:31:10 +00005370 if (setup_confname_tables(d))
5371 return;
5372
Barry Warsawca74da41999-02-09 19:31:45 +00005373 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005374
Guido van Rossumb3d39562000-01-31 18:41:26 +00005375#ifdef HAVE_PUTENV
Fred Drake762e2061999-08-26 17:23:54 +00005376 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00005377#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005378}