blob: 1a40d9e878a65cff3ab2c5278d0c18263f53730d [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009******************************************************************/
10
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011/* POSIX module implementation */
12
Guido van Rossuma4916fa1996-05-23 22:58:55 +000013/* This file is also used for Windows NT and MS-Win. In that case the module
Guido van Rossumad0ee831995-03-01 10:34:45 +000014 actually calls itself 'nt', not 'posix', and a few functions are
15 either unimplemented or implemented differently. The source
Guido van Rossum8d665e61996-06-26 18:22:49 +000016 assumes that for Windows NT, the macro 'MS_WIN32' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +000017 of the compiler used. Different compilers define their own feature
Guido van Rossuma4916fa1996-05-23 22:58:55 +000018 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000019
Guido van Rossuma4916fa1996-05-23 22:58:55 +000020/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000021
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000022static char posix__doc__ [] =
23"This module provides access to operating system functionality that is\n\
24standardized by the C Standard and the POSIX standard (a thinly\n\
25disguised Unix interface). Refer to the library manual and\n\
26corresponding Unix manual entries for more information on calls.";
27
Barry Warsaw53699e91996-12-10 23:23:01 +000028#include "Python.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000029
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000030#if defined(PYOS_OS2)
31#define INCL_DOS
32#define INCL_DOSERRORS
33#define INCL_DOSPROCESS
34#define INCL_NOPMAPI
35#include <os2.h>
36#endif
37
Guido van Rossumb6775db1994-08-01 11:34:53 +000038#include <sys/types.h>
39#include <sys/stat.h>
Guido van Rossum36bc6801995-06-14 22:54:23 +000040#ifdef HAVE_SYS_WAIT_H
41#include <sys/wait.h> /* For WNOHANG */
42#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000043
Guido van Rossuma376cc51996-12-05 23:43:35 +000044#ifdef HAVE_SIGNAL_H
45#include <signal.h>
46#endif
47
Guido van Rossumb6775db1994-08-01 11:34:53 +000048#include "mytime.h" /* For clock_t on some systems */
49
50#ifdef HAVE_FCNTL_H
51#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000052#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000053
Guido van Rossuma4916fa1996-05-23 22:58:55 +000054/* Various compilers have only certain posix functions */
Guido van Rossum6d8841c1997-08-14 19:57:39 +000055/* XXX Gosh I wish these were all moved into config.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000056#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000057#include <process.h>
58#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000059#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000060#define HAVE_GETCWD 1
61#define HAVE_OPENDIR 1
62#define HAVE_SYSTEM 1
63#if defined(__OS2__)
64#define HAVE_EXECV 1
65#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000066#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000067#include <process.h>
68#else
69#ifdef __BORLANDC__ /* Borland compiler */
70#define HAVE_EXECV 1
71#define HAVE_GETCWD 1
72#define HAVE_GETEGID 1
73#define HAVE_GETEUID 1
74#define HAVE_GETGID 1
75#define HAVE_GETPPID 1
76#define HAVE_GETUID 1
77#define HAVE_KILL 1
78#define HAVE_OPENDIR 1
79#define HAVE_PIPE 1
80#define HAVE_POPEN 1
81#define HAVE_SYSTEM 1
82#define HAVE_WAIT 1
83#else
84#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000085#define HAVE_GETCWD 1
86#ifdef MS_WIN32
Guido van Rossuma1065681999-01-25 23:20:23 +000087#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000088#define HAVE_EXECV 1
89#define HAVE_PIPE 1
90#define HAVE_POPEN 1
91#define HAVE_SYSTEM 1
92#else /* 16-bit Windows */
Guido van Rossum8d665e61996-06-26 18:22:49 +000093#endif /* !MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000094#else /* all other compilers */
95/* Unix functions that the configure script doesn't check for */
96#define HAVE_EXECV 1
97#define HAVE_FORK 1
98#define HAVE_GETCWD 1
99#define HAVE_GETEGID 1
100#define HAVE_GETEUID 1
101#define HAVE_GETGID 1
102#define HAVE_GETPPID 1
103#define HAVE_GETUID 1
104#define HAVE_KILL 1
105#define HAVE_OPENDIR 1
106#define HAVE_PIPE 1
107#define HAVE_POPEN 1
108#define HAVE_SYSTEM 1
109#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000110#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000111#endif /* _MSC_VER */
112#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000113#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000114#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000115
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000116#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000117
Guido van Rossumb6775db1994-08-01 11:34:53 +0000118#ifdef HAVE_UNISTD_H
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000119#include <unistd.h>
Guido van Rossum36bc6801995-06-14 22:54:23 +0000120#endif
121
122#ifdef NeXT
123/* NeXT's <unistd.h> and <utime.h> aren't worth much */
124#undef HAVE_UNISTD_H
125#undef HAVE_UTIME_H
Guido van Rossumb9f866c1997-05-22 15:12:39 +0000126#define HAVE_WAITPID
Guido van Rossum36bc6801995-06-14 22:54:23 +0000127/* #undef HAVE_GETCWD */
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000128#define UNION_WAIT /* This should really be checked for by autoconf */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000129#endif
130
131#ifdef HAVE_UNISTD_H
Guido van Rossumad0ee831995-03-01 10:34:45 +0000132/* XXX These are for SunOS4.1.3 but shouldn't hurt elsewhere */
133extern int rename();
134extern int pclose();
135extern int lstat();
136extern int symlink();
Guido van Rossum8c67e4e1999-04-07 15:49:41 +0000137extern int fsync();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000138#else /* !HAVE_UNISTD_H */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000139#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000140extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000141#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000142#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000143extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000144#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000145extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000146#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000147#endif
148#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000149extern int chdir(char *);
150extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000151#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000152extern int chdir(const char *);
153extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000154#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000155extern int chmod(const char *, mode_t);
156extern int chown(const char *, uid_t, gid_t);
157extern char *getcwd(char *, int);
158extern char *strerror(int);
159extern int link(const char *, const char *);
160extern int rename(const char *, const char *);
161extern int stat(const char *, struct stat *);
162extern int unlink(const char *);
163extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000164#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000165extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000166#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000167#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000168extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000169#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000170#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000171
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000172#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000173
Guido van Rossumb6775db1994-08-01 11:34:53 +0000174#ifdef HAVE_UTIME_H
175#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000176#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000177
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000178#ifdef HAVE_SYS_UTIME_H
179#include <sys/utime.h>
180#define HAVE_UTIME_H /* pretend we do for the rest of this file */
181#endif /* HAVE_SYS_UTIME_H */
182
Guido van Rossumb6775db1994-08-01 11:34:53 +0000183#ifdef HAVE_SYS_TIMES_H
184#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000185#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000186
187#ifdef HAVE_SYS_PARAM_H
188#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000189#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000190
191#ifdef HAVE_SYS_UTSNAME_H
192#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000193#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000194
195#ifndef MAXPATHLEN
196#define MAXPATHLEN 1024
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000197#endif /* MAXPATHLEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000198
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000199#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000200#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000201#define NAMLEN(dirent) strlen((dirent)->d_name)
202#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000203#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000204#include <direct.h>
205#define NAMLEN(dirent) strlen((dirent)->d_name)
206#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000207#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000208#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000209#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000210#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000212#endif
213#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000215#endif
216#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000218#endif
219#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000220
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000221#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000222#include <direct.h>
223#include <io.h>
224#include <process.h>
225#include <windows.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000226#ifdef MS_WIN32
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000227#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000228#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000229#else /* 16-bit Windows */
230#include <dos.h>
231#include <ctype.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000232#endif /* MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000233#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234
Guido van Rossumd48f2521997-12-05 22:19:34 +0000235#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000236#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000237#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000238
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000239#ifdef UNION_WAIT
240/* Emulate some macros on systems that have a union instead of macros */
241
242#ifndef WIFEXITED
243#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
244#endif
245
246#ifndef WEXITSTATUS
247#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
248#endif
249
250#ifndef WTERMSIG
251#define WTERMSIG(u_wait) ((u_wait).w_termsig)
252#endif
253
254#endif /* UNION_WAIT */
255
Greg Wardb48bc172000-03-01 21:51:56 +0000256/* Don't use the "_r" form if we don't need it (also, won't have a
257 prototype for it, at least on Solaris -- maybe others as well?). */
258#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
259#define USE_CTERMID_R
260#endif
261
262#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
263#define USE_TMPNAM_R
264#endif
265
Fred Drake699f3522000-06-29 21:12:41 +0000266/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000267#undef STAT
Fred Drake699f3522000-06-29 21:12:41 +0000268#ifdef MS_WIN64
269# define STAT _stati64
270# define FSTAT _fstati64
271# define STRUCT_STAT struct _stati64
272#else
273# define STAT stat
274# define FSTAT fstat
275# define STRUCT_STAT struct stat
276#endif
277
278
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000279/* Return a dictionary corresponding to the POSIX environment table */
280
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000281#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000282extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000283#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000284
Barry Warsaw53699e91996-12-10 23:23:01 +0000285static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000286convertenviron()
287{
Barry Warsaw53699e91996-12-10 23:23:01 +0000288 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000289 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000290 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000291 if (d == NULL)
292 return NULL;
293 if (environ == NULL)
294 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000295 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000296 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000297 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000298 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000299 char *p = strchr(*e, '=');
300 if (p == NULL)
301 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000302 k = PyString_FromStringAndSize(*e, (int)(p-*e));
303 if (k == NULL) {
304 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000305 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000306 }
307 v = PyString_FromString(p+1);
308 if (v == NULL) {
309 PyErr_Clear();
310 Py_DECREF(k);
311 continue;
312 }
313 if (PyDict_GetItem(d, k) == NULL) {
314 if (PyDict_SetItem(d, k, v) != 0)
315 PyErr_Clear();
316 }
317 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000318 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000319 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000320#if defined(PYOS_OS2)
321 {
322 APIRET rc;
323 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
324
325 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000326 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000327 PyObject *v = PyString_FromString(buffer);
328 PyDict_SetItemString(d, "BEGINLIBPATH", v);
329 Py_DECREF(v);
330 }
331 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
332 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
333 PyObject *v = PyString_FromString(buffer);
334 PyDict_SetItemString(d, "ENDLIBPATH", v);
335 Py_DECREF(v);
336 }
337 }
338#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000339 return d;
340}
341
342
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000343/* Set a POSIX-specific error from errno, and return NULL */
344
Barry Warsawd58d7641998-07-23 16:14:40 +0000345static PyObject *
346posix_error()
Guido van Rossumad0ee831995-03-01 10:34:45 +0000347{
Barry Warsawca74da41999-02-09 19:31:45 +0000348 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000349}
Barry Warsawd58d7641998-07-23 16:14:40 +0000350static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000351posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000352{
Barry Warsawca74da41999-02-09 19:31:45 +0000353 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000354}
355
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000356
Guido van Rossumd48f2521997-12-05 22:19:34 +0000357#if defined(PYOS_OS2)
358/**********************************************************************
359 * Helper Function to Trim and Format OS/2 Messages
360 **********************************************************************/
361 static void
362os2_formatmsg(char *msgbuf, int msglen, char *reason)
363{
364 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
365
366 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
367 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
368
369 while (lastc > msgbuf && isspace(*lastc))
370 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
371 }
372
373 /* Add Optional Reason Text */
374 if (reason) {
375 strcat(msgbuf, " : ");
376 strcat(msgbuf, reason);
377 }
378}
379
380/**********************************************************************
381 * Decode an OS/2 Operating System Error Code
382 *
383 * A convenience function to lookup an OS/2 error code and return a
384 * text message we can use to raise a Python exception.
385 *
386 * Notes:
387 * The messages for errors returned from the OS/2 kernel reside in
388 * the file OSO001.MSG in the \OS2 directory hierarchy.
389 *
390 **********************************************************************/
391 static char *
392os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
393{
394 APIRET rc;
395 ULONG msglen;
396
397 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
398 Py_BEGIN_ALLOW_THREADS
399 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
400 errorcode, "oso001.msg", &msglen);
401 Py_END_ALLOW_THREADS
402
403 if (rc == NO_ERROR)
404 os2_formatmsg(msgbuf, msglen, reason);
405 else
406 sprintf(msgbuf, "unknown OS error #%d", errorcode);
407
408 return msgbuf;
409}
410
411/* Set an OS/2-specific error and return NULL. OS/2 kernel
412 errors are not in a global variable e.g. 'errno' nor are
413 they congruent with posix error numbers. */
414
415static PyObject * os2_error(int code)
416{
417 char text[1024];
418 PyObject *v;
419
420 os2_strerror(text, sizeof(text), code, "");
421
422 v = Py_BuildValue("(is)", code, text);
423 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000424 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000425 Py_DECREF(v);
426 }
427 return NULL; /* Signal to Python that an Exception is Pending */
428}
429
430#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000431
432/* POSIX generic methods */
433
Barry Warsaw53699e91996-12-10 23:23:01 +0000434static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000435posix_int(PyObject *args, char *format, int (*func)(int))
Guido van Rossum21142a01999-01-08 21:05:37 +0000436{
437 int fd;
438 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000439 if (!PyArg_ParseTuple(args, format, &fd))
Guido van Rossum21142a01999-01-08 21:05:37 +0000440 return NULL;
441 Py_BEGIN_ALLOW_THREADS
442 res = (*func)(fd);
443 Py_END_ALLOW_THREADS
444 if (res < 0)
445 return posix_error();
446 Py_INCREF(Py_None);
447 return Py_None;
448}
449
450
451static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000452posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000453{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000454 char *path1;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000455 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000456 if (!PyArg_ParseTuple(args, format, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000457 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000458 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000459 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000460 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000461 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000462 return posix_error_with_filename(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000463 Py_INCREF(Py_None);
464 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000465}
466
Barry Warsaw53699e91996-12-10 23:23:01 +0000467static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000468posix_2str(PyObject *args, char *format,
469 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000470{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000471 char *path1, *path2;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000472 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000473 if (!PyArg_ParseTuple(args, format, &path1, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000474 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000475 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000476 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000477 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000478 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000479 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000480 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000481 Py_INCREF(Py_None);
482 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000483}
484
Barry Warsaw53699e91996-12-10 23:23:01 +0000485static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000486posix_strint(PyObject *args, char *format, int (*func)(const char *, int))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000487{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000488 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000489 int i;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000490 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000491 if (!PyArg_ParseTuple(args, format, &path, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000492 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000493 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000494 res = (*func)(path, i);
Barry Warsaw53699e91996-12-10 23:23:01 +0000495 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000496 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000497 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +0000498 Py_INCREF(Py_None);
499 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000500}
501
Barry Warsaw53699e91996-12-10 23:23:01 +0000502static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000503posix_strintint(PyObject *args, char *format,
504 int (*func)(const char *, int, int))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000505{
506 char *path;
507 int i,i2;
508 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000509 if (!PyArg_ParseTuple(args, format, &path, &i, &i2))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000510 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000511 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb6775db1994-08-01 11:34:53 +0000512 res = (*func)(path, i, i2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000513 Py_END_ALLOW_THREADS
Guido van Rossumb6775db1994-08-01 11:34:53 +0000514 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000515 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +0000516 Py_INCREF(Py_None);
517 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000518}
519
Fred Drake699f3522000-06-29 21:12:41 +0000520
521
522/* pack a system stat C structure into the Python stat tuple
523 (used by posix_stat() and posix_fstat()) */
524static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000525_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000526{
527 PyObject *v = PyTuple_New(10);
528 if (v == NULL)
529 return NULL;
530
531 PyTuple_SetItem(v, 0, PyInt_FromLong((long)st.st_mode));
532#ifdef HAVE_LARGEFILE_SUPPORT
533 PyTuple_SetItem(v, 1, PyLong_FromLongLong((LONG_LONG)st.st_ino));
534#else
535 PyTuple_SetItem(v, 1, PyInt_FromLong((long)st.st_ino));
536#endif
537#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
538 PyTuple_SetItem(v, 2, PyLong_FromLongLong((LONG_LONG)st.st_dev));
539#else
540 PyTuple_SetItem(v, 2, PyInt_FromLong((long)st.st_dev));
541#endif
542 PyTuple_SetItem(v, 3, PyInt_FromLong((long)st.st_nlink));
543 PyTuple_SetItem(v, 4, PyInt_FromLong((long)st.st_uid));
544 PyTuple_SetItem(v, 5, PyInt_FromLong((long)st.st_gid));
545#ifdef HAVE_LARGEFILE_SUPPORT
546 PyTuple_SetItem(v, 6, PyLong_FromLongLong((LONG_LONG)st.st_size));
547#else
548 PyTuple_SetItem(v, 6, PyInt_FromLong(st.st_size));
549#endif
550#if SIZEOF_TIME_T > SIZEOF_LONG
551 PyTuple_SetItem(v, 7, PyLong_FromLongLong((LONG_LONG)st.st_atime));
552 PyTuple_SetItem(v, 8, PyLong_FromLongLong((LONG_LONG)st.st_mtime));
553 PyTuple_SetItem(v, 9, PyLong_FromLongLong((LONG_LONG)st.st_ctime));
554#else
555 PyTuple_SetItem(v, 7, PyInt_FromLong((long)st.st_atime));
556 PyTuple_SetItem(v, 8, PyInt_FromLong((long)st.st_mtime));
557 PyTuple_SetItem(v, 9, PyInt_FromLong((long)st.st_ctime));
558#endif
559
560 if (PyErr_Occurred()) {
561 Py_DECREF(v);
562 return NULL;
563 }
564
565 return v;
566}
567
568
Barry Warsaw53699e91996-12-10 23:23:01 +0000569static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000570posix_do_stat(PyObject *self, PyObject *args, char *format,
571 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000572{
Fred Drake699f3522000-06-29 21:12:41 +0000573 STRUCT_STAT st;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000574 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000575 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000576
577#ifdef MS_WIN32
578 int pathlen;
579 char pathcopy[MAX_PATH];
580#endif /* MS_WIN32 */
581
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000582 if (!PyArg_ParseTuple(args, format, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000583 return NULL;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000584
585#ifdef MS_WIN32
586 pathlen = strlen(path);
587 /* the library call can blow up if the file name is too long! */
588 if (pathlen > MAX_PATH) {
589 errno = ENAMETOOLONG;
590 return posix_error();
591 }
592
593 if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) {
Guido van Rossum19dde102000-05-03 02:44:55 +0000594 /* exception for specific or current drive root */
595 if (!((pathlen == 1) ||
596 ((pathlen == 3) &&
Guido van Rossumace88ae2000-04-21 18:54:45 +0000597 (path[1] == ':') &&
Guido van Rossum19dde102000-05-03 02:44:55 +0000598 (path[2] == '\\' || path[2] == '/'))))
Guido van Rossumace88ae2000-04-21 18:54:45 +0000599 {
600 strncpy(pathcopy, path, pathlen);
601 pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */
602 path = pathcopy;
603 }
604 }
605#endif /* MS_WIN32 */
606
Barry Warsaw53699e91996-12-10 23:23:01 +0000607 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000608 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000609 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000610 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000611 return posix_error_with_filename(path);
Fred Drake699f3522000-06-29 21:12:41 +0000612
613 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000614}
615
616
617/* POSIX methods */
618
Guido van Rossum94f6f721999-01-06 18:42:14 +0000619static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000620"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000621Test for access to a file.";
622
623static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000624posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000625{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000626 char *path;
627 int mode;
628 int res;
629
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000630 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000631 return NULL;
632 Py_BEGIN_ALLOW_THREADS
633 res = access(path, mode);
634 Py_END_ALLOW_THREADS
635 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000636}
637
Guido van Rossumd371ff11999-01-25 16:12:23 +0000638#ifndef F_OK
639#define F_OK 0
640#endif
641#ifndef R_OK
642#define R_OK 4
643#endif
644#ifndef W_OK
645#define W_OK 2
646#endif
647#ifndef X_OK
648#define X_OK 1
649#endif
650
651#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000652static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000653"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000654Return the name of the terminal device connected to 'fd'.";
655
656static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000657posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000658{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000659 int id;
660 char *ret;
661
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000662 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000663 return NULL;
664
Guido van Rossum94f6f721999-01-06 18:42:14 +0000665 ret = ttyname(id);
666 if (ret == NULL)
667 return(posix_error());
668 return(PyString_FromString(ret));
669}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000670#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000671
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000672#ifdef HAVE_CTERMID
673static char posix_ctermid__doc__[] =
674"ctermid() -> String\n\
675Return the name of the controlling terminal for this process.";
676
677static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000678posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000679{
680 char *ret;
681 char buffer[L_ctermid];
682
683 if (!PyArg_ParseTuple(args, ":ctermid"))
684 return NULL;
685
Greg Wardb48bc172000-03-01 21:51:56 +0000686#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000687 ret = ctermid_r(buffer);
688#else
689 ret = ctermid(buffer);
690#endif
691 if (ret == NULL)
692 return(posix_error());
693 return(PyString_FromString(buffer));
694}
695#endif
696
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000697static char posix_chdir__doc__[] =
698"chdir(path) -> None\n\
699Change the current working directory to the specified path.";
700
Barry Warsaw53699e91996-12-10 23:23:01 +0000701static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000702posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000703{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000704 return posix_1str(args, "s:chdir", chdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000705}
706
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000707
708static char posix_chmod__doc__[] =
709"chmod(path, mode) -> None\n\
710Change the access permissions of a file.";
711
Barry Warsaw53699e91996-12-10 23:23:01 +0000712static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000713posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000714{
Guido van Rossumffd15f52000-03-31 00:47:28 +0000715 char *path;
716 int i;
717 int res;
Guido van Rossum49679b42000-03-31 00:48:21 +0000718 if (!PyArg_ParseTuple(args, "si", &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000719 return NULL;
720 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000721 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000722 Py_END_ALLOW_THREADS
723 if (res < 0)
724 return posix_error_with_filename(path);
725 Py_INCREF(Py_None);
726 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000727}
728
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000729
Guido van Rossum21142a01999-01-08 21:05:37 +0000730#ifdef HAVE_FSYNC
731static char posix_fsync__doc__[] =
732"fsync(fildes) -> None\n\
733force write of file with filedescriptor to disk.";
734
735static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000736posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000737{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000738 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000739}
740#endif /* HAVE_FSYNC */
741
742#ifdef HAVE_FDATASYNC
743static char posix_fdatasync__doc__[] =
744"fdatasync(fildes) -> None\n\
745force write of file with filedescriptor to disk.\n\
746 does not force update of metadata.";
747
Guido van Rossum5d00b6d1999-01-08 21:28:05 +0000748extern int fdatasync(int); /* Prototype just in case */
749
Guido van Rossum21142a01999-01-08 21:05:37 +0000750static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000751posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000752{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000753 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000754}
755#endif /* HAVE_FDATASYNC */
756
757
Guido van Rossumb6775db1994-08-01 11:34:53 +0000758#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000759static char posix_chown__doc__[] =
760"chown(path, uid, gid) -> None\n\
761Change the owner and group id of path to the numeric uid and gid.";
762
Barry Warsaw53699e91996-12-10 23:23:01 +0000763static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000764posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000765{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000766 return posix_strintint(args, "sii:chown", chown);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000767}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000768#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000769
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000770
Guido van Rossum36bc6801995-06-14 22:54:23 +0000771#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000772static char posix_getcwd__doc__[] =
773"getcwd() -> path\n\
774Return a string representing the current working directory.";
775
Barry Warsaw53699e91996-12-10 23:23:01 +0000776static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000777posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000778{
779 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000780 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000781 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000782 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000783 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000784 res = getcwd(buf, sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +0000785 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000786 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000787 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000788 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000789}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000790#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000791
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000792
Guido van Rossumb6775db1994-08-01 11:34:53 +0000793#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000794static char posix_link__doc__[] =
795"link(src, dst) -> None\n\
796Create a hard link to a file.";
797
Barry Warsaw53699e91996-12-10 23:23:01 +0000798static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000799posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000800{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000801 return posix_2str(args, "ss:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000802}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000803#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000804
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000805
806static char posix_listdir__doc__[] =
807"listdir(path) -> list_of_strings\n\
808Return a list containing the names of the entries in the directory.\n\
809\n\
810 path: path of directory to list\n\
811\n\
812The list is in arbitrary order. It does not include the special\n\
813entries '.' and '..' even if they are present in the directory.";
814
Barry Warsaw53699e91996-12-10 23:23:01 +0000815static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000816posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000817{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000818 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000819 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000820#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000821
Guido van Rossumb6775db1994-08-01 11:34:53 +0000822 char *name;
823 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000824 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000825 HANDLE hFindFile;
826 WIN32_FIND_DATA FileData;
827 char namebuf[MAX_PATH+5];
828
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000829 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000830 return NULL;
831 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000832 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000833 return NULL;
834 }
835 strcpy(namebuf, name);
836 if (namebuf[len-1] != '/' && namebuf[len-1] != '\\')
837 namebuf[len++] = '/';
838 strcpy(namebuf + len, "*.*");
839
Barry Warsaw53699e91996-12-10 23:23:01 +0000840 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000841 return NULL;
842
843 hFindFile = FindFirstFile(namebuf, &FileData);
844 if (hFindFile == INVALID_HANDLE_VALUE) {
845 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000846 if (errno == ERROR_FILE_NOT_FOUND)
847 return PyList_New(0);
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000848 return posix_error_with_filename(name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000849 }
850 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000851 if (FileData.cFileName[0] == '.' &&
852 (FileData.cFileName[1] == '\0' ||
853 FileData.cFileName[1] == '.' &&
854 FileData.cFileName[2] == '\0'))
855 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +0000856 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000857 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000858 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000859 d = NULL;
860 break;
861 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000862 if (PyList_Append(d, v) != 0) {
863 Py_DECREF(v);
864 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000865 d = NULL;
866 break;
867 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000868 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000869 } while (FindNextFile(hFindFile, &FileData) == TRUE);
870
871 if (FindClose(hFindFile) == FALSE) {
872 errno = GetLastError();
Andrew M. Kuchling54c8dc22000-06-06 20:52:17 +0000873 return posix_error_with_filename(name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000874 }
875
876 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000877
Guido van Rossum8d665e61996-06-26 18:22:49 +0000878#else /* !MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000879#ifdef _MSC_VER /* 16-bit Windows */
880
881#ifndef MAX_PATH
882#define MAX_PATH 250
883#endif
884 char *name, *pt;
885 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000886 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000887 char namebuf[MAX_PATH+5];
888 struct _find_t ep;
889
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000890 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000891 return NULL;
892 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000893 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000894 return NULL;
895 }
896 strcpy(namebuf, name);
897 for (pt = namebuf; *pt; pt++)
898 if (*pt == '/')
899 *pt = '\\';
900 if (namebuf[len-1] != '\\')
901 namebuf[len++] = '\\';
902 strcpy(namebuf + len, "*.*");
903
Barry Warsaw53699e91996-12-10 23:23:01 +0000904 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000905 return NULL;
906
907 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +0000908 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
909 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000910 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000911 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000912 }
913 do {
914 if (ep.name[0] == '.' &&
915 (ep.name[1] == '\0' ||
916 ep.name[1] == '.' &&
917 ep.name[2] == '\0'))
918 continue;
919 strcpy(namebuf, ep.name);
920 for (pt = namebuf; *pt; pt++)
921 if (isupper(*pt))
922 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +0000923 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000924 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000925 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000926 d = NULL;
927 break;
928 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000929 if (PyList_Append(d, v) != 0) {
930 Py_DECREF(v);
931 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000932 d = NULL;
933 break;
934 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000935 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000936 } while (_dos_findnext(&ep) == 0);
937
938 return d;
939
940#else
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000941#if defined(PYOS_OS2)
942
943#ifndef MAX_PATH
944#define MAX_PATH CCHMAXPATH
945#endif
946 char *name, *pt;
947 int len;
948 PyObject *d, *v;
949 char namebuf[MAX_PATH+5];
950 HDIR hdir = 1;
951 ULONG srchcnt = 1;
952 FILEFINDBUF3 ep;
953 APIRET rc;
954
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000955 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000956 return NULL;
957 if (len >= MAX_PATH) {
958 PyErr_SetString(PyExc_ValueError, "path too long");
959 return NULL;
960 }
961 strcpy(namebuf, name);
962 for (pt = namebuf; *pt; pt++)
963 if (*pt == '/')
964 *pt = '\\';
965 if (namebuf[len-1] != '\\')
966 namebuf[len++] = '\\';
967 strcpy(namebuf + len, "*.*");
968
969 if ((d = PyList_New(0)) == NULL)
970 return NULL;
971
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000972 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
973 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000974 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000975 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
976 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
977 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000978
979 if (rc != NO_ERROR) {
980 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000981 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000982 }
983
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000984 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000985 do {
986 if (ep.achName[0] == '.'
987 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000988 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000989
990 strcpy(namebuf, ep.achName);
991
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000992 /* Leave Case of Name Alone -- In Native Form */
993 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000994
995 v = PyString_FromString(namebuf);
996 if (v == NULL) {
997 Py_DECREF(d);
998 d = NULL;
999 break;
1000 }
1001 if (PyList_Append(d, v) != 0) {
1002 Py_DECREF(v);
1003 Py_DECREF(d);
1004 d = NULL;
1005 break;
1006 }
1007 Py_DECREF(v);
1008 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1009 }
1010
1011 return d;
1012#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001013
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001014 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001015 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001016 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001017 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001018 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001019 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001020 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001021 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001022 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001023 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001024 closedir(dirp);
1025 return NULL;
1026 }
1027 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001028 if (ep->d_name[0] == '.' &&
1029 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001030 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001031 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001032 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001033 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001034 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001035 d = NULL;
1036 break;
1037 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001038 if (PyList_Append(d, v) != 0) {
1039 Py_DECREF(v);
1040 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001041 d = NULL;
1042 break;
1043 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001044 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001045 }
1046 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001047
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001048 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001049
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001050#endif /* !PYOS_OS2 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001051#endif /* !_MSC_VER */
Guido van Rossum8d665e61996-06-26 18:22:49 +00001052#endif /* !MS_WIN32 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001053}
1054
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001055static char posix_mkdir__doc__[] =
1056"mkdir(path [, mode=0777]) -> None\n\
1057Create a directory.";
1058
Barry Warsaw53699e91996-12-10 23:23:01 +00001059static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001060posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001061{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001062 int res;
1063 char *path;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001064 int mode = 0777;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001065 if (!PyArg_ParseTuple(args, "s|i:mkdir", &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001066 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001067 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001068#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001069 res = mkdir(path);
1070#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001071 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001072#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001073 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001074 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001075 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001076 Py_INCREF(Py_None);
1077 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001078}
1079
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001080
Guido van Rossumb6775db1994-08-01 11:34:53 +00001081#ifdef HAVE_NICE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001082static char posix_nice__doc__[] =
1083"nice(inc) -> new_priority\n\
1084Decrease the priority of process and return new priority.";
1085
Barry Warsaw53699e91996-12-10 23:23:01 +00001086static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001087posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001088{
1089 int increment, value;
1090
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001091 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001092 return NULL;
1093 value = nice(increment);
1094 if (value == -1)
1095 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001096 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001097}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001098#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001099
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001100
1101static char posix_rename__doc__[] =
1102"rename(old, new) -> None\n\
1103Rename a file or directory.";
1104
Barry Warsaw53699e91996-12-10 23:23:01 +00001105static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001106posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001107{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001108 return posix_2str(args, "ss:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001109}
1110
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001111
1112static char posix_rmdir__doc__[] =
1113"rmdir(path) -> None\n\
1114Remove a directory.";
1115
Barry Warsaw53699e91996-12-10 23:23:01 +00001116static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001117posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001118{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001119 return posix_1str(args, "s:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001120}
1121
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001122
1123static char posix_stat__doc__[] =
1124"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1125Perform a stat system call on the given path.";
1126
Barry Warsaw53699e91996-12-10 23:23:01 +00001127static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001128posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001129{
Fred Drake699f3522000-06-29 21:12:41 +00001130 return posix_do_stat(self, args, "s:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001131}
1132
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001133
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001134#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001135static char posix_system__doc__[] =
1136"system(command) -> exit_status\n\
1137Execute the command (a string) in a subshell.";
1138
Barry Warsaw53699e91996-12-10 23:23:01 +00001139static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001140posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001141{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001142 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001143 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001144 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001145 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001146 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001147 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001148 Py_END_ALLOW_THREADS
1149 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001150}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001151#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001152
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001153
1154static char posix_umask__doc__[] =
1155"umask(new_mask) -> old_mask\n\
1156Set the current numeric umask and return the previous umask.";
1157
Barry Warsaw53699e91996-12-10 23:23:01 +00001158static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001159posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001160{
1161 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001162 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001163 return NULL;
1164 i = umask(i);
1165 if (i < 0)
1166 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001167 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001168}
1169
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001170
1171static char posix_unlink__doc__[] =
1172"unlink(path) -> None\n\
1173Remove a file (same as remove(path)).";
1174
1175static char posix_remove__doc__[] =
1176"remove(path) -> None\n\
1177Remove a file (same as unlink(path)).";
1178
Barry Warsaw53699e91996-12-10 23:23:01 +00001179static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001180posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001181{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001182 return posix_1str(args, "s:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001183}
1184
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001185
Guido van Rossumb6775db1994-08-01 11:34:53 +00001186#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001187static char posix_uname__doc__[] =
1188"uname() -> (sysname, nodename, release, version, machine)\n\
1189Return a tuple identifying the current operating system.";
1190
Barry Warsaw53699e91996-12-10 23:23:01 +00001191static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001192posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001193{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001194 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001195 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001196 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001197 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001198 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001199 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001200 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001201 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001202 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001203 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001204 u.sysname,
1205 u.nodename,
1206 u.release,
1207 u.version,
1208 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001209}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001210#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001211
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001212
1213static char posix_utime__doc__[] =
1214"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001215utime(path, None) -> None\n\
1216Set the access and modified time of the file to the given values. If the\n\
1217second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001218
Barry Warsaw53699e91996-12-10 23:23:01 +00001219static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001220posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001221{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001222 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001223 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001224 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001225 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001226
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001227/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001228#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001229 struct utimbuf buf;
1230#define ATIME buf.actime
1231#define MTIME buf.modtime
1232#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001233#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001234 time_t buf[2];
1235#define ATIME buf[0]
1236#define MTIME buf[1]
1237#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001238#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001239
Barry Warsaw3cef8562000-05-01 16:17:24 +00001240 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001241 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001242 if (arg == Py_None) {
1243 /* optional time values not given */
1244 Py_BEGIN_ALLOW_THREADS
1245 res = utime(path, NULL);
1246 Py_END_ALLOW_THREADS
1247 }
1248 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1249 PyErr_SetString(PyExc_TypeError,
1250 "Second argument must be a 2-tuple of numbers.");
1251 return NULL;
1252 }
1253 else {
1254 ATIME = atime;
1255 MTIME = mtime;
1256 Py_BEGIN_ALLOW_THREADS
1257 res = utime(path, UTIME_ARG);
1258 Py_END_ALLOW_THREADS
1259 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001260 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001261 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001262 Py_INCREF(Py_None);
1263 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001264#undef UTIME_ARG
1265#undef ATIME
1266#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001267}
1268
Guido van Rossum85e3b011991-06-03 12:42:10 +00001269
Guido van Rossum3b066191991-06-04 19:40:25 +00001270/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001271
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001272static char posix__exit__doc__[] =
1273"_exit(status)\n\
1274Exit to the system with specified status, without normal exit processing.";
1275
Barry Warsaw53699e91996-12-10 23:23:01 +00001276static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001277posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001278{
1279 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001280 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001281 return NULL;
1282 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001283 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001284}
1285
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001286
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001287#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001288static char posix_execv__doc__[] =
1289"execv(path, args)\n\
1290Execute an executable path with arguments, replacing current process.\n\
1291\n\
1292 path: path of executable file\n\
1293 args: tuple or list of strings";
1294
Barry Warsaw53699e91996-12-10 23:23:01 +00001295static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001296posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001297{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001298 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001299 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001300 char **argvlist;
1301 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001302 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001303
Guido van Rossum89b33251993-10-22 14:26:06 +00001304 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001305 argv is a list or tuple of strings. */
1306
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001307 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001308 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001309 if (PyList_Check(argv)) {
1310 argc = PyList_Size(argv);
1311 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001312 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001313 else if (PyTuple_Check(argv)) {
1314 argc = PyTuple_Size(argv);
1315 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001316 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001317 else {
Guido van Rossum50422b42000-04-26 20:34:28 +00001318 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
1319 return NULL;
1320 }
1321
1322 if (argc == 0) {
1323 PyErr_SetString(PyExc_ValueError, "empty argument list");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001324 return NULL;
1325 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001326
Barry Warsaw53699e91996-12-10 23:23:01 +00001327 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001328 if (argvlist == NULL)
1329 return NULL;
1330 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001331 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1332 PyMem_DEL(argvlist);
Guido van Rossum50422b42000-04-26 20:34:28 +00001333 PyErr_SetString(PyExc_TypeError,
1334 "all arguments must be strings");
1335 return NULL;
1336
Guido van Rossum85e3b011991-06-03 12:42:10 +00001337 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001338 }
1339 argvlist[argc] = NULL;
1340
Guido van Rossumb6775db1994-08-01 11:34:53 +00001341#ifdef BAD_EXEC_PROTOTYPES
1342 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001343#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001344 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001345#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001346
Guido van Rossum85e3b011991-06-03 12:42:10 +00001347 /* If we get here it's definitely an error */
1348
Barry Warsaw53699e91996-12-10 23:23:01 +00001349 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001350 return posix_error();
1351}
1352
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001353
1354static char posix_execve__doc__[] =
1355"execve(path, args, env)\n\
1356Execute a path with arguments and environment, replacing current process.\n\
1357\n\
1358 path: path of executable file\n\
1359 args: tuple or list of arguments\n\
1360 env: dictonary of strings mapping to strings";
1361
Barry Warsaw53699e91996-12-10 23:23:01 +00001362static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001363posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001364{
1365 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001366 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001367 char **argvlist;
1368 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001369 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001370 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001371 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001372
1373 /* execve has three arguments: (path, argv, env), where
1374 argv is a list or tuple of strings and env is a dictionary
1375 like posix.environ. */
1376
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001377 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001378 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001379 if (PyList_Check(argv)) {
1380 argc = PyList_Size(argv);
1381 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001382 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001383 else if (PyTuple_Check(argv)) {
1384 argc = PyTuple_Size(argv);
1385 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001386 }
1387 else {
Barry Warsaw53699e91996-12-10 23:23:01 +00001388 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001389 return NULL;
1390 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001391 if (!PyMapping_Check(env)) {
1392 PyErr_SetString(PyExc_TypeError, "env must be mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001393 return NULL;
1394 }
1395
Guido van Rossum50422b42000-04-26 20:34:28 +00001396 if (argc == 0) {
1397 PyErr_SetString(PyExc_ValueError,
1398 "empty argument list");
1399 return NULL;
1400 }
1401
Barry Warsaw53699e91996-12-10 23:23:01 +00001402 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001403 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001404 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001405 return NULL;
1406 }
1407 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001408 if (!PyArg_Parse((*getitem)(argv, i),
Barry Warsaw43d68b81996-12-19 22:10:44 +00001409 "s;argv must be list of strings",
1410 &argvlist[i]))
1411 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001412 goto fail_1;
1413 }
1414 }
1415 argvlist[argc] = NULL;
1416
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001417 i = PyMapping_Length(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001418 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001419 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001420 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001421 goto fail_1;
1422 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001423 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001424 keys = PyMapping_Keys(env);
1425 vals = PyMapping_Values(env);
1426 if (!keys || !vals)
1427 goto fail_2;
1428
1429 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001430 char *p, *k, *v;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001431
1432 key = PyList_GetItem(keys, pos);
1433 val = PyList_GetItem(vals, pos);
1434 if (!key || !val)
1435 goto fail_2;
1436
Barry Warsaw53699e91996-12-10 23:23:01 +00001437 if (!PyArg_Parse(key, "s;non-string key in env", &k) ||
Barry Warsaw43d68b81996-12-19 22:10:44 +00001438 !PyArg_Parse(val, "s;non-string value in env", &v))
1439 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001440 goto fail_2;
1441 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001442
1443#if defined(PYOS_OS2)
1444 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1445 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1446#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001447 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001448 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001449 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001450 goto fail_2;
1451 }
1452 sprintf(p, "%s=%s", k, v);
1453 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001454#if defined(PYOS_OS2)
1455 }
1456#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001457 }
1458 envlist[envc] = 0;
1459
Guido van Rossumb6775db1994-08-01 11:34:53 +00001460
1461#ifdef BAD_EXEC_PROTOTYPES
1462 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001463#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001464 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001465#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001466
1467 /* If we get here it's definitely an error */
1468
1469 (void) posix_error();
1470
1471 fail_2:
1472 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001473 PyMem_DEL(envlist[envc]);
1474 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001475 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001476 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001477 Py_XDECREF(vals);
1478 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001479 return NULL;
1480}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001481#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001482
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001483
Guido van Rossuma1065681999-01-25 23:20:23 +00001484#ifdef HAVE_SPAWNV
1485static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001486"spawnv(mode, path, args)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001487Execute an executable path with arguments, replacing current process.\n\
1488\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001489 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001490 path: path of executable file\n\
1491 args: tuple or list of strings";
1492
1493static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001494posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001495{
1496 char *path;
1497 PyObject *argv;
1498 char **argvlist;
1499 int mode, i, argc;
Fred Drake699f3522000-06-29 21:12:41 +00001500 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001501 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001502
1503 /* spawnv has three arguments: (mode, path, argv), where
1504 argv is a list or tuple of strings. */
1505
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001506 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001507 return NULL;
1508 if (PyList_Check(argv)) {
1509 argc = PyList_Size(argv);
1510 getitem = PyList_GetItem;
1511 }
1512 else if (PyTuple_Check(argv)) {
1513 argc = PyTuple_Size(argv);
1514 getitem = PyTuple_GetItem;
1515 }
1516 else {
Fred Drake137507e2000-06-01 02:02:46 +00001517 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001518 return NULL;
1519 }
1520
1521 argvlist = PyMem_NEW(char *, argc+1);
1522 if (argvlist == NULL)
1523 return NULL;
1524 for (i = 0; i < argc; i++) {
1525 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1526 PyMem_DEL(argvlist);
Fred Drake137507e2000-06-01 02:02:46 +00001527 PyErr_SetString(PyExc_TypeError,
1528 "all arguments must be strings");
1529 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001530 }
1531 }
1532 argvlist[argc] = NULL;
1533
Guido van Rossum246bc171999-02-01 23:54:31 +00001534 if (mode == _OLD_P_OVERLAY)
1535 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001536 spawnval = _spawnv(mode, path, argvlist);
Guido van Rossuma1065681999-01-25 23:20:23 +00001537
1538 PyMem_DEL(argvlist);
1539
Fred Drake699f3522000-06-29 21:12:41 +00001540 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001541 return posix_error();
1542 else
Fred Drake699f3522000-06-29 21:12:41 +00001543#if SIZEOF_LONG == SIZE_VOID_P
1544 return Py_BuildValue("l", spawnval);
1545#else
1546 return Py_BuildValue("L", spawnval);
1547#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001548}
1549
1550
1551static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001552"spawnve(mode, path, args, env)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001553Execute a path with arguments and environment, replacing current process.\n\
1554\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001555 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001556 path: path of executable file\n\
1557 args: tuple or list of arguments\n\
1558 env: dictonary of strings mapping to strings";
1559
1560static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001561posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001562{
1563 char *path;
1564 PyObject *argv, *env;
1565 char **argvlist;
1566 char **envlist;
1567 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1568 int mode, i, pos, argc, envc;
Fred Drake699f3522000-06-29 21:12:41 +00001569 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001570 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001571
1572 /* spawnve has four arguments: (mode, path, argv, env), where
1573 argv is a list or tuple of strings and env is a dictionary
1574 like posix.environ. */
1575
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001576 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001577 return NULL;
1578 if (PyList_Check(argv)) {
1579 argc = PyList_Size(argv);
1580 getitem = PyList_GetItem;
1581 }
1582 else if (PyTuple_Check(argv)) {
1583 argc = PyTuple_Size(argv);
1584 getitem = PyTuple_GetItem;
1585 }
1586 else {
1587 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
1588 return NULL;
1589 }
1590 if (!PyMapping_Check(env)) {
1591 PyErr_SetString(PyExc_TypeError, "env must be mapping object");
1592 return NULL;
1593 }
1594
1595 argvlist = PyMem_NEW(char *, argc+1);
1596 if (argvlist == NULL) {
1597 PyErr_NoMemory();
1598 return NULL;
1599 }
1600 for (i = 0; i < argc; i++) {
1601 if (!PyArg_Parse((*getitem)(argv, i),
1602 "s;argv must be list of strings",
1603 &argvlist[i]))
1604 {
1605 goto fail_1;
1606 }
1607 }
1608 argvlist[argc] = NULL;
1609
1610 i = PyMapping_Length(env);
1611 envlist = PyMem_NEW(char *, i + 1);
1612 if (envlist == NULL) {
1613 PyErr_NoMemory();
1614 goto fail_1;
1615 }
1616 envc = 0;
1617 keys = PyMapping_Keys(env);
1618 vals = PyMapping_Values(env);
1619 if (!keys || !vals)
1620 goto fail_2;
1621
1622 for (pos = 0; pos < i; pos++) {
1623 char *p, *k, *v;
1624
1625 key = PyList_GetItem(keys, pos);
1626 val = PyList_GetItem(vals, pos);
1627 if (!key || !val)
1628 goto fail_2;
1629
1630 if (!PyArg_Parse(key, "s;non-string key in env", &k) ||
1631 !PyArg_Parse(val, "s;non-string value in env", &v))
1632 {
1633 goto fail_2;
1634 }
1635 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1636 if (p == NULL) {
1637 PyErr_NoMemory();
1638 goto fail_2;
1639 }
1640 sprintf(p, "%s=%s", k, v);
1641 envlist[envc++] = p;
1642 }
1643 envlist[envc] = 0;
1644
Guido van Rossum246bc171999-02-01 23:54:31 +00001645 if (mode == _OLD_P_OVERLAY)
1646 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001647 spawnval = _spawnve(mode, path, argvlist, envlist);
1648 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001649 (void) posix_error();
1650 else
Fred Drake699f3522000-06-29 21:12:41 +00001651#if SIZEOF_LONG == SIZE_VOID_P
1652 res = Py_BuildValue("l", spawnval);
1653#else
1654 res = Py_BuildValue("L", spawnval);
1655#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001656
1657 fail_2:
1658 while (--envc >= 0)
1659 PyMem_DEL(envlist[envc]);
1660 PyMem_DEL(envlist);
1661 fail_1:
1662 PyMem_DEL(argvlist);
1663 Py_XDECREF(vals);
1664 Py_XDECREF(keys);
1665 return res;
1666}
1667#endif /* HAVE_SPAWNV */
1668
1669
Guido van Rossumad0ee831995-03-01 10:34:45 +00001670#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001671static char posix_fork__doc__[] =
1672"fork() -> pid\n\
1673Fork a child process.\n\
1674\n\
1675Return 0 to child process and PID of child to parent process.";
1676
Barry Warsaw53699e91996-12-10 23:23:01 +00001677static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001678posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001679{
1680 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001681 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001682 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001683 pid = fork();
1684 if (pid == -1)
1685 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001686 if (pid == 0)
1687 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001688 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001689}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001690#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001691
Fred Drake8cef4cf2000-06-28 16:40:38 +00001692#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1693#ifdef HAVE_PTY_H
1694#include <pty.h>
1695#else
1696#ifdef HAVE_LIBUTIL_H
1697#include <libutil.h>
1698#else
1699/* BSDI does not supply a prototype for the 'openpty' and 'forkpty'
1700 functions, eventhough they are included in libutil. */
1701#include <termios.h>
1702extern int openpty(int *, int *, char *, struct termios *, struct winsize *);
1703extern int forkpty(int *, char *, struct termios *, struct winsize *);
1704#endif /* HAVE_LIBUTIL_H */
1705#endif /* HAVE_PTY_H */
1706#endif /* defined(HAVE_OPENPTY) or defined(HAVE_FORKPTY) */
1707
1708#ifdef HAVE_OPENPTY
1709static char posix_openpty__doc__[] =
1710"openpty() -> (master_fd, slave_fd)\n\
1711Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1712
1713static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001714posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001715{
1716 int master_fd, slave_fd;
1717 if (!PyArg_ParseTuple(args, ":openpty"))
1718 return NULL;
1719 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1720 return posix_error();
1721 return Py_BuildValue("(ii)", master_fd, slave_fd);
1722}
1723#endif
1724
1725#ifdef HAVE_FORKPTY
1726static char posix_forkpty__doc__[] =
1727"forkpty() -> (pid, master_fd)\n\
1728Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1729Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1730To both, return fd of newly opened pseudo-terminal.\n";
1731
1732static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001733posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001734{
1735 int master_fd, pid;
1736
1737 if (!PyArg_ParseTuple(args, ":forkpty"))
1738 return NULL;
1739 pid = forkpty(&master_fd, NULL, NULL, NULL);
1740 if (pid == -1)
1741 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001742 if (pid == 0)
1743 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001744 return Py_BuildValue("(ii)", pid, master_fd);
1745}
1746#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001747
Guido van Rossumad0ee831995-03-01 10:34:45 +00001748#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001749static char posix_getegid__doc__[] =
1750"getegid() -> egid\n\
1751Return the current process's effective group id.";
1752
Barry Warsaw53699e91996-12-10 23:23:01 +00001753static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001754posix_getegid(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, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001757 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001758 return PyInt_FromLong((long)getegid());
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_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001764static char posix_geteuid__doc__[] =
1765"geteuid() -> euid\n\
1766Return the current process's effective user id.";
1767
Barry Warsaw53699e91996-12-10 23:23:01 +00001768static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001769posix_geteuid(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, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001772 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001773 return PyInt_FromLong((long)geteuid());
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
Guido van Rossumad0ee831995-03-01 10:34:45 +00001778#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001779static char posix_getgid__doc__[] =
1780"getgid() -> gid\n\
1781Return the current process's group id.";
1782
Barry Warsaw53699e91996-12-10 23:23:01 +00001783static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001784posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001785{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001786 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001787 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001788 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001789}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001790#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001791
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001792
1793static char posix_getpid__doc__[] =
1794"getpid() -> pid\n\
1795Return the current process id";
1796
Barry Warsaw53699e91996-12-10 23:23:01 +00001797static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001798posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001799{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001800 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001801 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001802 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001803}
1804
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001805
Fred Drakec9680921999-12-13 16:37:25 +00001806#ifdef HAVE_GETGROUPS
1807static char posix_getgroups__doc__[] = "\
1808getgroups() -> list of group IDs\n\
1809Return list of supplemental group IDs for the process.";
1810
1811static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001812posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00001813{
1814 PyObject *result = NULL;
1815
1816 if (PyArg_ParseTuple(args, ":getgroups")) {
1817#ifdef NGROUPS_MAX
1818#define MAX_GROUPS NGROUPS_MAX
1819#else
1820 /* defined to be 16 on Solaris7, so this should be a small number */
1821#define MAX_GROUPS 64
1822#endif
1823 gid_t grouplist[MAX_GROUPS];
1824 int n;
1825
1826 n = getgroups(MAX_GROUPS, grouplist);
1827 if (n < 0)
1828 posix_error();
1829 else {
1830 result = PyList_New(n);
1831 if (result != NULL) {
1832 PyObject *o;
1833 int i;
1834 for (i = 0; i < n; ++i) {
1835 o = PyInt_FromLong((long)grouplist[i]);
1836 if (o == NULL) {
1837 Py_DECREF(result);
1838 result = NULL;
1839 break;
1840 }
1841 PyList_SET_ITEM(result, i, o);
1842 }
1843 }
1844 }
1845 }
1846 return result;
1847}
1848#endif
1849
Guido van Rossumb6775db1994-08-01 11:34:53 +00001850#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001851static char posix_getpgrp__doc__[] =
1852"getpgrp() -> pgrp\n\
1853Return the current process group id.";
1854
Barry Warsaw53699e91996-12-10 23:23:01 +00001855static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001856posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00001857{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001858 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00001859 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001860#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00001861 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001862#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00001863 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001864#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00001865}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001866#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00001867
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001868
Guido van Rossumb6775db1994-08-01 11:34:53 +00001869#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001870static char posix_setpgrp__doc__[] =
1871"setpgrp() -> None\n\
1872Make this process a session leader.";
1873
Barry Warsaw53699e91996-12-10 23:23:01 +00001874static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001875posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00001876{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001877 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00001878 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00001879#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00001880 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001881#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001882 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001883#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00001884 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001885 Py_INCREF(Py_None);
1886 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00001887}
1888
Guido van Rossumb6775db1994-08-01 11:34:53 +00001889#endif /* HAVE_SETPGRP */
1890
Guido van Rossumad0ee831995-03-01 10:34:45 +00001891#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001892static char posix_getppid__doc__[] =
1893"getppid() -> ppid\n\
1894Return the parent's process id.";
1895
Barry Warsaw53699e91996-12-10 23:23:01 +00001896static PyObject *
Guido van Rossum85e3b011991-06-03 12:42:10 +00001897posix_getppid(self, args)
Barry Warsaw53699e91996-12-10 23:23:01 +00001898 PyObject *self;
1899 PyObject *args;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001900{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001901 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001902 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001903 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001904}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001905#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001906
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001907
Fred Drake12c6e2d1999-12-14 21:25:03 +00001908#ifdef HAVE_GETLOGIN
1909static char posix_getlogin__doc__[] = "\
1910getlogin() -> string\n\
1911Return the actual login name.";
1912
1913static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001914posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00001915{
1916 PyObject *result = NULL;
1917
1918 if (PyArg_ParseTuple(args, ":getlogin")) {
1919 char *name = getlogin();
1920
1921 if (name == NULL)
1922 posix_error();
1923 else
1924 result = PyString_FromString(name);
1925 }
1926 return result;
1927}
1928#endif
1929
Guido van Rossumad0ee831995-03-01 10:34:45 +00001930#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001931static char posix_getuid__doc__[] =
1932"getuid() -> uid\n\
1933Return the current process's user id.";
1934
Barry Warsaw53699e91996-12-10 23:23:01 +00001935static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001936posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001937{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001938 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001939 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001940 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001941}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001942#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001943
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001944
Guido van Rossumad0ee831995-03-01 10:34:45 +00001945#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001946static char posix_kill__doc__[] =
1947"kill(pid, sig) -> None\n\
1948Kill a process with a signal.";
1949
Barry Warsaw53699e91996-12-10 23:23:01 +00001950static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001951posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001952{
1953 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001954 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001955 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001956#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001957 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
1958 APIRET rc;
1959 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001960 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001961
1962 } else if (sig == XCPT_SIGNAL_KILLPROC) {
1963 APIRET rc;
1964 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001965 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001966
1967 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001968 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001969#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00001970 if (kill(pid, sig) == -1)
1971 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001972#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001973 Py_INCREF(Py_None);
1974 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001975}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001976#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001977
Guido van Rossumc0125471996-06-28 18:55:32 +00001978#ifdef HAVE_PLOCK
1979
1980#ifdef HAVE_SYS_LOCK_H
1981#include <sys/lock.h>
1982#endif
1983
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001984static char posix_plock__doc__[] =
1985"plock(op) -> None\n\
1986Lock program segments into memory.";
1987
Barry Warsaw53699e91996-12-10 23:23:01 +00001988static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001989posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00001990{
1991 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001992 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00001993 return NULL;
1994 if (plock(op) == -1)
1995 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001996 Py_INCREF(Py_None);
1997 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00001998}
1999#endif
2000
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002001
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002002#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002003static char posix_popen__doc__[] =
2004"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2005Open a pipe to/from a command returning a file object.";
2006
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002007#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002008static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002009async_system(const char *command)
2010{
2011 char *p, errormsg[256], args[1024];
2012 RESULTCODES rcodes;
2013 APIRET rc;
2014 char *shell = getenv("COMSPEC");
2015 if (!shell)
2016 shell = "cmd";
2017
2018 strcpy(args, shell);
2019 p = &args[ strlen(args)+1 ];
2020 strcpy(p, "/c ");
2021 strcat(p, command);
2022 p += strlen(p) + 1;
2023 *p = '\0';
2024
2025 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002026 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002027 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002028 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002029 &rcodes, shell);
2030 return rc;
2031}
2032
Guido van Rossumd48f2521997-12-05 22:19:34 +00002033static FILE *
2034popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002035{
2036 HFILE rhan, whan;
2037 FILE *retfd = NULL;
2038 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2039
Guido van Rossumd48f2521997-12-05 22:19:34 +00002040 if (rc != NO_ERROR) {
2041 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002042 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002043 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002044
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002045 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2046 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002047
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002048 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2049 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002050
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002051 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2052 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002053
2054 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002055 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002056 }
2057
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002058 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2059 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002060
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002061 close(oldfd); /* And Close Saved STDOUT Handle */
2062 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002063
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002064 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2065 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002066
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002067 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2068 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002069
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002070 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2071 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002072
2073 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002074 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002075 }
2076
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002077 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2078 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002079
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002080 close(oldfd); /* And Close Saved STDIN Handle */
2081 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002082
Guido van Rossumd48f2521997-12-05 22:19:34 +00002083 } else {
2084 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002085 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002086 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002087}
2088
2089static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002090posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002091{
2092 char *name;
2093 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002094 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002095 FILE *fp;
2096 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002097 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002098 return NULL;
2099 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002100 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002101 Py_END_ALLOW_THREADS
2102 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002103 return os2_error(err);
2104
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002105 f = PyFile_FromFile(fp, name, mode, fclose);
2106 if (f != NULL)
2107 PyFile_SetBufSize(f, bufsize);
2108 return f;
2109}
2110
2111#else
Barry Warsaw53699e91996-12-10 23:23:01 +00002112static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002113posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00002114{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002115 char *name;
2116 char *mode = "r";
2117 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00002118 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00002119 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002120 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00002121 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002122 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002123 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00002124 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00002125 if (fp == NULL)
2126 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002127 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002128 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00002129 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002130 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00002131}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002132#endif
2133
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002134#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00002135
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002136
Guido van Rossumb6775db1994-08-01 11:34:53 +00002137#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002138static char posix_setuid__doc__[] =
2139"setuid(uid) -> None\n\
2140Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00002141static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002142posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002143{
2144 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002145 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002146 return NULL;
2147 if (setuid(uid) < 0)
2148 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002149 Py_INCREF(Py_None);
2150 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002151}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002152#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002153
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002154
Guido van Rossumb6775db1994-08-01 11:34:53 +00002155#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002156static char posix_setgid__doc__[] =
2157"setgid(gid) -> None\n\
2158Set the current process's group id.";
2159
Barry Warsaw53699e91996-12-10 23:23:01 +00002160static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002161posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002162{
2163 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002164 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002165 return NULL;
2166 if (setgid(gid) < 0)
2167 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002168 Py_INCREF(Py_None);
2169 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002170}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002171#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002172
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002173
Guido van Rossumb6775db1994-08-01 11:34:53 +00002174#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002175static char posix_waitpid__doc__[] =
2176"waitpid(pid, options) -> (pid, status)\n\
2177Wait for completion of a give child process.";
2178
Barry Warsaw53699e91996-12-10 23:23:01 +00002179static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002180posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002181{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002182 int pid, options;
2183#ifdef UNION_WAIT
2184 union wait status;
2185#define status_i (status.w_status)
2186#else
2187 int status;
2188#define status_i status
2189#endif
2190 status_i = 0;
2191
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002192 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00002193 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002194 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00002195#ifdef NeXT
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002196 pid = wait4(pid, &status, options, NULL);
Guido van Rossume6a3aa61999-02-01 16:15:30 +00002197#else
2198 pid = waitpid(pid, &status, options);
2199#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002200 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00002201 if (pid == -1)
2202 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00002203 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002204 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00002205}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002206#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +00002207
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002208
Guido van Rossumad0ee831995-03-01 10:34:45 +00002209#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002210static char posix_wait__doc__[] =
2211"wait() -> (pid, status)\n\
2212Wait for completion of a child process.";
2213
Barry Warsaw53699e91996-12-10 23:23:01 +00002214static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002215posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00002216{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002217 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002218#ifdef UNION_WAIT
2219 union wait status;
2220#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00002221#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002222 int status;
2223#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00002224#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002225 if (!PyArg_ParseTuple(args, ":wait"))
2226 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002227 status_i = 0;
2228 Py_BEGIN_ALLOW_THREADS
2229 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00002230 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00002231 if (pid == -1)
2232 return posix_error();
2233 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002234 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002235#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00002236}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002237#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002238
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002239
2240static char posix_lstat__doc__[] =
2241"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
2242Like stat(path), but do not follow symbolic links.";
2243
Barry Warsaw53699e91996-12-10 23:23:01 +00002244static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002245posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002246{
Guido van Rossumb6775db1994-08-01 11:34:53 +00002247#ifdef HAVE_LSTAT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002248 return posix_do_stat(self, args, "s:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002249#else /* !HAVE_LSTAT */
Fred Drake699f3522000-06-29 21:12:41 +00002250 return posix_do_stat(self, args, "s:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002251#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002252}
2253
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002254
Guido van Rossumb6775db1994-08-01 11:34:53 +00002255#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002256static char posix_readlink__doc__[] =
2257"readlink(path) -> path\n\
2258Return a string representing the path to which the symbolic link points.";
2259
Barry Warsaw53699e91996-12-10 23:23:01 +00002260static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002261posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002262{
Guido van Rossumb6775db1994-08-01 11:34:53 +00002263 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002264 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002265 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002266 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002267 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002268 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00002269 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00002270 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002271 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00002272 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002273 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002274}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002275#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002276
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002277
Guido van Rossumb6775db1994-08-01 11:34:53 +00002278#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002279static char posix_symlink__doc__[] =
2280"symlink(src, dst) -> None\n\
2281Create a symbolic link.";
2282
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002283static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002284posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002285{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002286 return posix_2str(args, "ss:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002287}
2288#endif /* HAVE_SYMLINK */
2289
2290
2291#ifdef HAVE_TIMES
2292#ifndef HZ
2293#define HZ 60 /* Universal constant :-) */
2294#endif /* HZ */
2295
Guido van Rossumd48f2521997-12-05 22:19:34 +00002296#if defined(PYCC_VACPP) && defined(PYOS_OS2)
2297static long
2298system_uptime()
2299{
2300 ULONG value = 0;
2301
2302 Py_BEGIN_ALLOW_THREADS
2303 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
2304 Py_END_ALLOW_THREADS
2305
2306 return value;
2307}
2308
2309static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002310posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002311{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002312 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00002313 return NULL;
2314
2315 /* Currently Only Uptime is Provided -- Others Later */
2316 return Py_BuildValue("ddddd",
2317 (double)0 /* t.tms_utime / HZ */,
2318 (double)0 /* t.tms_stime / HZ */,
2319 (double)0 /* t.tms_cutime / HZ */,
2320 (double)0 /* t.tms_cstime / HZ */,
2321 (double)system_uptime() / 1000);
2322}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002323#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00002324static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002325posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00002326{
2327 struct tms t;
2328 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002329 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00002330 return NULL;
2331 errno = 0;
2332 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00002333 if (c == (clock_t) -1)
2334 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002335 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002336 (double)t.tms_utime / HZ,
2337 (double)t.tms_stime / HZ,
2338 (double)t.tms_cutime / HZ,
2339 (double)t.tms_cstime / HZ,
2340 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00002341}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002342#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002343#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002344
2345
Guido van Rossum87755a21996-09-07 00:59:43 +00002346#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00002347#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00002348static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002349posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00002350{
2351 FILETIME create, exit, kernel, user;
2352 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002353 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00002354 return NULL;
2355 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00002356 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
2357 /* The fields of a FILETIME structure are the hi and lo part
2358 of a 64-bit value expressed in 100 nanosecond units.
2359 1e7 is one second in such units; 1e-7 the inverse.
2360 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
2361 */
Barry Warsaw53699e91996-12-10 23:23:01 +00002362 return Py_BuildValue(
2363 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00002364 (double)(kernel.dwHighDateTime*429.4967296 +
2365 kernel.dwLowDateTime*1e-7),
2366 (double)(user.dwHighDateTime*429.4967296 +
2367 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00002368 (double)0,
2369 (double)0,
2370 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00002371}
Guido van Rossum8d665e61996-06-26 18:22:49 +00002372#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002373
2374#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00002375static char posix_times__doc__[] =
2376"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
2377Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002378#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00002379
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002380
Guido van Rossumb6775db1994-08-01 11:34:53 +00002381#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002382static char posix_setsid__doc__[] =
2383"setsid() -> None\n\
2384Call the system call setsid().";
2385
Barry Warsaw53699e91996-12-10 23:23:01 +00002386static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002387posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002388{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002389 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002390 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00002391 if (setsid() < 0)
2392 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002393 Py_INCREF(Py_None);
2394 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002395}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002396#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00002397
Guido van Rossumb6775db1994-08-01 11:34:53 +00002398#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002399static char posix_setpgid__doc__[] =
2400"setpgid(pid, pgrp) -> None\n\
2401Call the system call setpgid().";
2402
Barry Warsaw53699e91996-12-10 23:23:01 +00002403static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002404posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002405{
2406 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002407 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002408 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00002409 if (setpgid(pid, pgrp) < 0)
2410 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002411 Py_INCREF(Py_None);
2412 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002413}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002414#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00002415
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002416
Guido van Rossumb6775db1994-08-01 11:34:53 +00002417#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002418static char posix_tcgetpgrp__doc__[] =
2419"tcgetpgrp(fd) -> pgid\n\
2420Return the process group associated with the terminal given by a fd.";
2421
Barry Warsaw53699e91996-12-10 23:23:01 +00002422static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002423posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00002424{
2425 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002426 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00002427 return NULL;
2428 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00002429 if (pgid < 0)
2430 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002431 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00002432}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002433#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00002434
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002435
Guido van Rossumb6775db1994-08-01 11:34:53 +00002436#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002437static char posix_tcsetpgrp__doc__[] =
2438"tcsetpgrp(fd, pgid) -> None\n\
2439Set the process group associated with the terminal given by a fd.";
2440
Barry Warsaw53699e91996-12-10 23:23:01 +00002441static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002442posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00002443{
2444 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002445 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00002446 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00002447 if (tcsetpgrp(fd, pgid) < 0)
2448 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00002449 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00002450 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00002451}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002452#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00002453
Guido van Rossum687dd131993-05-17 08:34:16 +00002454/* Functions acting on file descriptors */
2455
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002456static char posix_open__doc__[] =
2457"open(filename, flag [, mode=0777]) -> fd\n\
2458Open a file (for low level IO).";
2459
Barry Warsaw53699e91996-12-10 23:23:01 +00002460static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002461posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00002462{
2463 char *file;
2464 int flag;
2465 int mode = 0777;
2466 int fd;
Barry Warsaw43d68b81996-12-19 22:10:44 +00002467 if (!PyArg_ParseTuple(args, "si|i", &file, &flag, &mode))
2468 return NULL;
2469
Barry Warsaw53699e91996-12-10 23:23:01 +00002470 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002471 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00002472 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002473 if (fd < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00002474 return posix_error_with_filename(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00002475 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00002476}
2477
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002478
2479static char posix_close__doc__[] =
2480"close(fd) -> None\n\
2481Close a file descriptor (for low level IO).";
2482
Barry Warsaw53699e91996-12-10 23:23:01 +00002483static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002484posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00002485{
2486 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002487 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00002488 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002489 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002490 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00002491 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002492 if (res < 0)
2493 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002494 Py_INCREF(Py_None);
2495 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00002496}
2497
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002498
2499static char posix_dup__doc__[] =
2500"dup(fd) -> fd2\n\
2501Return a duplicate of a file descriptor.";
2502
Barry Warsaw53699e91996-12-10 23:23:01 +00002503static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002504posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00002505{
2506 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002507 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00002508 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002509 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002510 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00002511 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002512 if (fd < 0)
2513 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002514 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00002515}
2516
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002517
2518static char posix_dup2__doc__[] =
2519"dup2(fd, fd2) -> None\n\
2520Duplicate file descriptor.";
2521
Barry Warsaw53699e91996-12-10 23:23:01 +00002522static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002523posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00002524{
2525 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002526 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00002527 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002528 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002529 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00002530 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002531 if (res < 0)
2532 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002533 Py_INCREF(Py_None);
2534 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00002535}
2536
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002537
2538static char posix_lseek__doc__[] =
2539"lseek(fd, pos, how) -> newpos\n\
2540Set the current position of a file descriptor.";
2541
Barry Warsaw53699e91996-12-10 23:23:01 +00002542static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002543posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00002544{
2545 int fd, how;
Fred Drake699f3522000-06-29 21:12:41 +00002546#ifdef MS_WIN64
2547 LONG_LONG pos, res;
2548#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00002549 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00002550#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002551 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002552 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00002553 return NULL;
2554#ifdef SEEK_SET
2555 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
2556 switch (how) {
2557 case 0: how = SEEK_SET; break;
2558 case 1: how = SEEK_CUR; break;
2559 case 2: how = SEEK_END; break;
2560 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002561#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00002562
2563#if !defined(HAVE_LARGEFILE_SUPPORT)
2564 pos = PyInt_AsLong(posobj);
2565#else
2566 pos = PyLong_Check(posobj) ?
2567 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
2568#endif
2569 if (PyErr_Occurred())
2570 return NULL;
2571
Barry Warsaw53699e91996-12-10 23:23:01 +00002572 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002573#ifdef MS_WIN64
2574 res = _lseeki64(fd, pos, how);
2575#else
Guido van Rossum687dd131993-05-17 08:34:16 +00002576 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00002577#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002578 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002579 if (res < 0)
2580 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00002581
2582#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00002583 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002584#else
2585 return PyLong_FromLongLong(res);
2586#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00002587}
2588
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002589
2590static char posix_read__doc__[] =
2591"read(fd, buffersize) -> string\n\
2592Read a file descriptor.";
2593
Barry Warsaw53699e91996-12-10 23:23:01 +00002594static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002595posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00002596{
Guido van Rossum8bac5461996-06-11 18:38:48 +00002597 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00002598 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002599 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00002600 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002601 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00002602 if (buffer == NULL)
2603 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002604 Py_BEGIN_ALLOW_THREADS
2605 n = read(fd, PyString_AsString(buffer), size);
2606 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00002607 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002608 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00002609 return posix_error();
2610 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00002611 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00002612 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00002613 return buffer;
2614}
2615
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002616
2617static char posix_write__doc__[] =
2618"write(fd, string) -> byteswritten\n\
2619Write a string to a file descriptor.";
2620
Barry Warsaw53699e91996-12-10 23:23:01 +00002621static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002622posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00002623{
2624 int fd, size;
2625 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002626 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00002627 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002628 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002629 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00002630 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002631 if (size < 0)
2632 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002633 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00002634}
2635
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002636
2637static char posix_fstat__doc__[]=
2638"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
2639Like stat(), but for an open file descriptor.";
2640
Barry Warsaw53699e91996-12-10 23:23:01 +00002641static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002642posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00002643{
2644 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00002645 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00002646 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002647 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00002648 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002649 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002650 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00002651 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002652 if (res != 0)
2653 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00002654
2655 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00002656}
2657
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002658
2659static char posix_fdopen__doc__[] =
2660"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
2661Return an open file object connected to a file descriptor.";
2662
Barry Warsaw53699e91996-12-10 23:23:01 +00002663static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002664posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00002665{
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002666 extern int fclose(FILE *);
Guido van Rossum687dd131993-05-17 08:34:16 +00002667 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002668 char *mode = "r";
2669 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00002670 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00002671 PyObject *f;
2672 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00002673 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00002674
Barry Warsaw53699e91996-12-10 23:23:01 +00002675 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002676 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00002677 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002678 if (fp == NULL)
2679 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002680 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002681 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00002682 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002683 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00002684}
2685
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002686
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002687#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002688static char posix_pipe__doc__[] =
2689"pipe() -> (read_end, write_end)\n\
2690Create a pipe.";
2691
Barry Warsaw53699e91996-12-10 23:23:01 +00002692static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002693posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00002694{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002695#if defined(PYOS_OS2)
2696 HFILE read, write;
2697 APIRET rc;
2698
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002699 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002700 return NULL;
2701
2702 Py_BEGIN_ALLOW_THREADS
2703 rc = DosCreatePipe( &read, &write, 4096);
2704 Py_END_ALLOW_THREADS
2705 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002706 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002707
2708 return Py_BuildValue("(ii)", read, write);
2709#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00002710#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00002711 int fds[2];
2712 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002713 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00002714 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002715 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002716 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00002717 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002718 if (res != 0)
2719 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002720 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00002721#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00002722 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00002723 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00002724 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002725 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00002726 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002727 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00002728 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00002729 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00002730 if (!ok)
2731 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00002732 read_fd = _open_osfhandle((intptr_t)read, 0);
2733 write_fd = _open_osfhandle((intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00002734 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00002735#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002736#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00002737}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002738#endif /* HAVE_PIPE */
2739
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002740
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002741#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002742static char posix_mkfifo__doc__[] =
2743"mkfifo(file, [, mode=0666]) -> None\n\
2744Create a FIFO (a POSIX named pipe).";
2745
Barry Warsaw53699e91996-12-10 23:23:01 +00002746static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002747posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002748{
2749 char *file;
2750 int mode = 0666;
2751 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002752 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002753 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002754 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002755 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00002756 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002757 if (res < 0)
2758 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002759 Py_INCREF(Py_None);
2760 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002761}
2762#endif
2763
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002764
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002765#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002766static char posix_ftruncate__doc__[] =
2767"ftruncate(fd, length) -> None\n\
2768Truncate a file to a specified length.";
2769
Barry Warsaw53699e91996-12-10 23:23:01 +00002770static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002771posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002772{
2773 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002774 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002775 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002776 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002777
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002778 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00002779 return NULL;
2780
2781#if !defined(HAVE_LARGEFILE_SUPPORT)
2782 length = PyInt_AsLong(lenobj);
2783#else
2784 length = PyLong_Check(lenobj) ?
2785 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
2786#endif
2787 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002788 return NULL;
2789
Barry Warsaw53699e91996-12-10 23:23:01 +00002790 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002791 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00002792 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002793 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002794 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002795 return NULL;
2796 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002797 Py_INCREF(Py_None);
2798 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002799}
2800#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00002801
Guido van Rossumb9f866c1997-05-22 15:12:39 +00002802#ifdef NeXT
2803#define HAVE_PUTENV
2804/* Steve Spicklemire got this putenv from NeXTAnswers */
2805static int
2806putenv(char *newval)
2807{
2808 extern char **environ;
2809
2810 static int firstTime = 1;
2811 char **ep;
2812 char *cp;
2813 int esiz;
2814 char *np;
2815
2816 if (!(np = strchr(newval, '=')))
2817 return 1;
2818 *np = '\0';
2819
2820 /* look it up */
2821 for (ep=environ ; *ep ; ep++)
2822 {
2823 /* this should always be true... */
2824 if (cp = strchr(*ep, '='))
2825 {
2826 *cp = '\0';
2827 if (!strcmp(*ep, newval))
2828 {
2829 /* got it! */
2830 *cp = '=';
2831 break;
2832 }
2833 *cp = '=';
2834 }
2835 else
2836 {
2837 *np = '=';
2838 return 1;
2839 }
2840 }
2841
2842 *np = '=';
2843 if (*ep)
2844 {
2845 /* the string was already there:
2846 just replace it with the new one */
2847 *ep = newval;
2848 return 0;
2849 }
2850
2851 /* expand environ by one */
2852 for (esiz=2, ep=environ ; *ep ; ep++)
2853 esiz++;
2854 if (firstTime)
2855 {
2856 char **epp;
2857 char **newenv;
2858 if (!(newenv = malloc(esiz * sizeof(char *))))
2859 return 1;
2860
2861 for (ep=environ, epp=newenv ; *ep ;)
2862 *epp++ = *ep++;
2863 *epp++ = newval;
2864 *epp = (char *) 0;
2865 environ = newenv;
2866 }
2867 else
2868 {
2869 if (!(environ = realloc(environ, esiz * sizeof(char *))))
2870 return 1;
2871 environ[esiz - 2] = newval;
2872 environ[esiz - 1] = (char *) 0;
2873 firstTime = 0;
2874 }
2875
2876 return 0;
2877}
Guido van Rossumc6ef2041997-08-21 02:30:45 +00002878#endif /* NeXT */
Guido van Rossumb9f866c1997-05-22 15:12:39 +00002879
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002880
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00002881#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002882static char posix_putenv__doc__[] =
2883"putenv(key, value) -> None\n\
2884Change or add an environment variable.";
2885
Guido van Rossumbcc20741998-08-04 22:53:56 +00002886#ifdef __BEOS__
2887/* We have putenv(), but not in the headers (as of PR2). - [cjh] */
2888int putenv( const char *str );
2889#endif
2890
Fred Drake762e2061999-08-26 17:23:54 +00002891/* Save putenv() parameters as values here, so we can collect them when they
2892 * get re-set with another call for the same key. */
2893static PyObject *posix_putenv_garbage;
2894
Barry Warsaw53699e91996-12-10 23:23:01 +00002895static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002896posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00002897{
2898 char *s1, *s2;
2899 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00002900 PyObject *newstr;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00002901
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002902 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00002903 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002904
2905#if defined(PYOS_OS2)
2906 if (stricmp(s1, "BEGINLIBPATH") == 0) {
2907 APIRET rc;
2908
2909 if (strlen(s2) == 0) /* If New Value is an Empty String */
2910 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
2911
2912 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
2913 if (rc != NO_ERROR)
2914 return os2_error(rc);
2915
2916 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
2917 APIRET rc;
2918
2919 if (strlen(s2) == 0) /* If New Value is an Empty String */
2920 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
2921
2922 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
2923 if (rc != NO_ERROR)
2924 return os2_error(rc);
2925 } else {
2926#endif
2927
Fred Drake762e2061999-08-26 17:23:54 +00002928 /* XXX This can leak memory -- not easy to fix :-( */
2929 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
2930 if (newstr == NULL)
2931 return PyErr_NoMemory();
2932 new = PyString_AS_STRING(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00002933 (void) sprintf(new, "%s=%s", s1, s2);
2934 if (putenv(new)) {
2935 posix_error();
2936 return NULL;
2937 }
Fred Drake762e2061999-08-26 17:23:54 +00002938 /* Install the first arg and newstr in posix_putenv_garbage;
2939 * this will cause previous value to be collected. This has to
2940 * happen after the real putenv() call because the old value
2941 * was still accessible until then. */
2942 if (PyDict_SetItem(posix_putenv_garbage,
2943 PyTuple_GET_ITEM(args, 0), newstr)) {
2944 /* really not much we can do; just leak */
2945 PyErr_Clear();
2946 }
2947 else {
2948 Py_DECREF(newstr);
2949 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002950
2951#if defined(PYOS_OS2)
2952 }
2953#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002954 Py_INCREF(Py_None);
2955 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00002956}
Guido van Rossumb6a47161997-09-15 22:54:34 +00002957#endif /* putenv */
2958
2959#ifdef HAVE_STRERROR
2960static char posix_strerror__doc__[] =
2961"strerror(code) -> string\n\
2962Translate an error code to a message string.";
2963
2964PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002965posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00002966{
2967 int code;
2968 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002969 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00002970 return NULL;
2971 message = strerror(code);
2972 if (message == NULL) {
2973 PyErr_SetString(PyExc_ValueError,
2974 "strerror code out of range");
2975 return NULL;
2976 }
2977 return PyString_FromString(message);
2978}
2979#endif /* strerror */
2980
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00002981
Guido van Rossumc9641791998-08-04 15:26:23 +00002982#ifdef HAVE_SYS_WAIT_H
2983
2984#ifdef WIFSTOPPED
2985static char posix_WIFSTOPPED__doc__[] =
2986"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00002987Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00002988
2989static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002990posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00002991{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002992#ifdef UNION_WAIT
2993 union wait status;
2994#define status_i (status.w_status)
2995#else
2996 int status;
2997#define status_i status
2998#endif
2999 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003000
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003001 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003002 {
3003 return NULL;
3004 }
3005
3006 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003007#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003008}
3009#endif /* WIFSTOPPED */
3010
3011#ifdef WIFSIGNALED
3012static char posix_WIFSIGNALED__doc__[] =
3013"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00003014Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003015
3016static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003017posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003018{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003019#ifdef UNION_WAIT
3020 union wait status;
3021#define status_i (status.w_status)
3022#else
3023 int status;
3024#define status_i status
3025#endif
3026 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003027
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003028 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003029 {
3030 return NULL;
3031 }
3032
3033 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003034#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003035}
3036#endif /* WIFSIGNALED */
3037
3038#ifdef WIFEXITED
3039static char posix_WIFEXITED__doc__[] =
3040"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003041Return true if the process returning 'status' exited using the exit()\n\
3042system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003043
3044static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003045posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003046{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003047#ifdef UNION_WAIT
3048 union wait status;
3049#define status_i (status.w_status)
3050#else
3051 int status;
3052#define status_i status
3053#endif
3054 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003055
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003056 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003057 {
3058 return NULL;
3059 }
3060
3061 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003062#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003063}
3064#endif /* WIFEXITED */
3065
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003066#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00003067static char posix_WEXITSTATUS__doc__[] =
3068"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003069Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003070
3071static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003072posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003073{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003074#ifdef UNION_WAIT
3075 union wait status;
3076#define status_i (status.w_status)
3077#else
3078 int status;
3079#define status_i status
3080#endif
3081 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003082
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003083 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003084 {
3085 return NULL;
3086 }
3087
3088 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003089#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003090}
3091#endif /* WEXITSTATUS */
3092
3093#ifdef WTERMSIG
3094static char posix_WTERMSIG__doc__[] =
3095"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003096Return the signal that terminated the process that provided the 'status'\n\
3097value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003098
3099static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003100posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003101{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003102#ifdef UNION_WAIT
3103 union wait status;
3104#define status_i (status.w_status)
3105#else
3106 int status;
3107#define status_i status
3108#endif
3109 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003110
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003111 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003112 {
3113 return NULL;
3114 }
3115
3116 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003117#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003118}
3119#endif /* WTERMSIG */
3120
3121#ifdef WSTOPSIG
3122static char posix_WSTOPSIG__doc__[] =
3123"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003124Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003125
3126static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003127posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003128{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003129#ifdef UNION_WAIT
3130 union wait status;
3131#define status_i (status.w_status)
3132#else
3133 int status;
3134#define status_i status
3135#endif
3136 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003137
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003138 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003139 {
3140 return NULL;
3141 }
3142
3143 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003144#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003145}
3146#endif /* WSTOPSIG */
3147
3148#endif /* HAVE_SYS_WAIT_H */
3149
3150
Guido van Rossum94f6f721999-01-06 18:42:14 +00003151#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00003152#ifdef _SCO_DS
3153/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
3154 needed definitions in sys/statvfs.h */
3155#define _SVID3
3156#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003157#include <sys/statvfs.h>
3158
3159static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003160"fstatvfs(fd) -> \n\
3161 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00003162Perform an fstatvfs system call on the given fd.";
3163
3164static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003165posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00003166{
3167 int fd, res;
3168 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003169 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003170 return NULL;
3171 Py_BEGIN_ALLOW_THREADS
3172 res = fstatvfs(fd, &st);
3173 Py_END_ALLOW_THREADS
3174 if (res != 0)
3175 return posix_error();
3176#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003177 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003178 (long) st.f_bsize,
3179 (long) st.f_frsize,
3180 (long) st.f_blocks,
3181 (long) st.f_bfree,
3182 (long) st.f_bavail,
3183 (long) st.f_files,
3184 (long) st.f_ffree,
3185 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003186 (long) st.f_flag,
3187 (long) st.f_namemax);
3188#else
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003189 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003190 (long) st.f_bsize,
3191 (long) st.f_frsize,
3192 (LONG_LONG) st.f_blocks,
3193 (LONG_LONG) st.f_bfree,
3194 (LONG_LONG) st.f_bavail,
3195 (LONG_LONG) st.f_files,
3196 (LONG_LONG) st.f_ffree,
3197 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003198 (long) st.f_flag,
3199 (long) st.f_namemax);
3200#endif
3201}
3202#endif /* HAVE_FSTATVFS */
3203
3204
3205#if defined(HAVE_STATVFS)
3206#include <sys/statvfs.h>
3207
3208static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003209"statvfs(path) -> \n\
3210 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00003211Perform a statvfs system call on the given path.";
3212
3213static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003214posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00003215{
3216 char *path;
3217 int res;
3218 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003219 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003220 return NULL;
3221 Py_BEGIN_ALLOW_THREADS
3222 res = statvfs(path, &st);
3223 Py_END_ALLOW_THREADS
3224 if (res != 0)
3225 return posix_error_with_filename(path);
3226#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003227 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003228 (long) st.f_bsize,
3229 (long) st.f_frsize,
3230 (long) st.f_blocks,
3231 (long) st.f_bfree,
3232 (long) st.f_bavail,
3233 (long) st.f_files,
3234 (long) st.f_ffree,
3235 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003236 (long) st.f_flag,
3237 (long) st.f_namemax);
3238#else /* HAVE_LARGEFILE_SUPPORT */
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003239 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003240 (long) st.f_bsize,
3241 (long) st.f_frsize,
3242 (LONG_LONG) st.f_blocks,
3243 (LONG_LONG) st.f_bfree,
3244 (LONG_LONG) st.f_bavail,
3245 (LONG_LONG) st.f_files,
3246 (LONG_LONG) st.f_ffree,
3247 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003248 (long) st.f_flag,
3249 (long) st.f_namemax);
3250#endif
3251}
3252#endif /* HAVE_STATVFS */
3253
3254
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003255#ifdef HAVE_TEMPNAM
3256static char posix_tempnam__doc__[] = "\
3257tempnam([dir[, prefix]]) -> string\n\
3258Return a unique name for a temporary file.\n\
3259The directory and a short may be specified as strings; they may be omitted\n\
3260or None if not needed.";
3261
3262static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003263posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003264{
3265 PyObject *result = NULL;
3266 char *dir = NULL;
3267 char *pfx = NULL;
3268 char *name;
3269
3270 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
3271 return NULL;
3272 name = tempnam(dir, pfx);
3273 if (name == NULL)
3274 return PyErr_NoMemory();
3275 result = PyString_FromString(name);
3276 free(name);
3277 return result;
3278}
Guido van Rossumd371ff11999-01-25 16:12:23 +00003279#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003280
3281
3282#ifdef HAVE_TMPFILE
3283static char posix_tmpfile__doc__[] = "\
3284tmpfile() -> file object\n\
3285Create a temporary file with no directory entries.";
3286
3287static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003288posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003289{
3290 FILE *fp;
3291
3292 if (!PyArg_ParseTuple(args, ":tmpfile"))
3293 return NULL;
3294 fp = tmpfile();
3295 if (fp == NULL)
3296 return posix_error();
3297 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
3298}
3299#endif
3300
3301
3302#ifdef HAVE_TMPNAM
3303static char posix_tmpnam__doc__[] = "\
3304tmpnam() -> string\n\
3305Return a unique name for a temporary file.";
3306
3307static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003308posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003309{
3310 char buffer[L_tmpnam];
3311 char *name;
3312
3313 if (!PyArg_ParseTuple(args, ":tmpnam"))
3314 return NULL;
Greg Wardb48bc172000-03-01 21:51:56 +00003315#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003316 name = tmpnam_r(buffer);
3317#else
3318 name = tmpnam(buffer);
3319#endif
3320 if (name == NULL) {
3321 PyErr_SetObject(PyExc_OSError,
3322 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00003323#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003324 "unexpected NULL from tmpnam_r"
3325#else
3326 "unexpected NULL from tmpnam"
3327#endif
3328 ));
3329 return NULL;
3330 }
3331 return PyString_FromString(buffer);
3332}
3333#endif
3334
3335
Fred Drakec9680921999-12-13 16:37:25 +00003336/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
3337 * It maps strings representing configuration variable names to
3338 * integer values, allowing those functions to be called with the
3339 * magic names instead of poluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00003340 * rarely-used constants. There are three separate tables that use
3341 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00003342 *
3343 * This code is always included, even if none of the interfaces that
3344 * need it are included. The #if hackery needed to avoid it would be
3345 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00003346 */
3347struct constdef {
3348 char *name;
3349 long value;
3350};
3351
Fred Drake12c6e2d1999-12-14 21:25:03 +00003352static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003353conv_confname(PyObject *arg, int *valuep, struct constdef *table,
3354 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003355{
3356 if (PyInt_Check(arg)) {
3357 *valuep = PyInt_AS_LONG(arg);
3358 return 1;
3359 }
3360 if (PyString_Check(arg)) {
3361 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00003362 size_t lo = 0;
3363 size_t mid;
3364 size_t hi = tablesize;
3365 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003366 char *confname = PyString_AS_STRING(arg);
3367 while (lo < hi) {
3368 mid = (lo + hi) / 2;
3369 cmp = strcmp(confname, table[mid].name);
3370 if (cmp < 0)
3371 hi = mid;
3372 else if (cmp > 0)
3373 lo = mid + 1;
3374 else {
3375 *valuep = table[mid].value;
3376 return 1;
3377 }
3378 }
3379 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
3380 }
3381 else
3382 PyErr_SetString(PyExc_TypeError,
3383 "configuration names must be strings or integers");
3384 return 0;
3385}
3386
3387
3388#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
3389static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00003390#ifdef _PC_ABI_AIO_XFER_MAX
3391 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
3392#endif
3393#ifdef _PC_ABI_ASYNC_IO
3394 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
3395#endif
Fred Drakec9680921999-12-13 16:37:25 +00003396#ifdef _PC_ASYNC_IO
3397 {"PC_ASYNC_IO", _PC_ASYNC_IO},
3398#endif
3399#ifdef _PC_CHOWN_RESTRICTED
3400 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
3401#endif
3402#ifdef _PC_FILESIZEBITS
3403 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
3404#endif
3405#ifdef _PC_LAST
3406 {"PC_LAST", _PC_LAST},
3407#endif
3408#ifdef _PC_LINK_MAX
3409 {"PC_LINK_MAX", _PC_LINK_MAX},
3410#endif
3411#ifdef _PC_MAX_CANON
3412 {"PC_MAX_CANON", _PC_MAX_CANON},
3413#endif
3414#ifdef _PC_MAX_INPUT
3415 {"PC_MAX_INPUT", _PC_MAX_INPUT},
3416#endif
3417#ifdef _PC_NAME_MAX
3418 {"PC_NAME_MAX", _PC_NAME_MAX},
3419#endif
3420#ifdef _PC_NO_TRUNC
3421 {"PC_NO_TRUNC", _PC_NO_TRUNC},
3422#endif
3423#ifdef _PC_PATH_MAX
3424 {"PC_PATH_MAX", _PC_PATH_MAX},
3425#endif
3426#ifdef _PC_PIPE_BUF
3427 {"PC_PIPE_BUF", _PC_PIPE_BUF},
3428#endif
3429#ifdef _PC_PRIO_IO
3430 {"PC_PRIO_IO", _PC_PRIO_IO},
3431#endif
3432#ifdef _PC_SOCK_MAXBUF
3433 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
3434#endif
3435#ifdef _PC_SYNC_IO
3436 {"PC_SYNC_IO", _PC_SYNC_IO},
3437#endif
3438#ifdef _PC_VDISABLE
3439 {"PC_VDISABLE", _PC_VDISABLE},
3440#endif
3441};
3442
Fred Drakec9680921999-12-13 16:37:25 +00003443static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003444conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00003445{
3446 return conv_confname(arg, valuep, posix_constants_pathconf,
3447 sizeof(posix_constants_pathconf)
3448 / sizeof(struct constdef));
3449}
3450#endif
3451
3452#ifdef HAVE_FPATHCONF
3453static char posix_fpathconf__doc__[] = "\
3454fpathconf(fd, name) -> integer\n\
3455Return the configuration limit name for the file descriptor fd.\n\
3456If there is no limit, return -1.";
3457
3458static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003459posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00003460{
3461 PyObject *result = NULL;
3462 int name, fd;
3463
Fred Drake12c6e2d1999-12-14 21:25:03 +00003464 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
3465 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00003466 long limit;
3467
3468 errno = 0;
3469 limit = fpathconf(fd, name);
3470 if (limit == -1 && errno != 0)
3471 posix_error();
3472 else
3473 result = PyInt_FromLong(limit);
3474 }
3475 return result;
3476}
3477#endif
3478
3479
3480#ifdef HAVE_PATHCONF
3481static char posix_pathconf__doc__[] = "\
3482pathconf(path, name) -> integer\n\
3483Return the configuration limit name for the file or directory path.\n\
3484If there is no limit, return -1.";
3485
3486static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003487posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00003488{
3489 PyObject *result = NULL;
3490 int name;
3491 char *path;
3492
3493 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
3494 conv_path_confname, &name)) {
3495 long limit;
3496
3497 errno = 0;
3498 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00003499 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00003500 if (errno == EINVAL)
3501 /* could be a path or name problem */
3502 posix_error();
3503 else
3504 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00003505 }
Fred Drakec9680921999-12-13 16:37:25 +00003506 else
3507 result = PyInt_FromLong(limit);
3508 }
3509 return result;
3510}
3511#endif
3512
3513#ifdef HAVE_CONFSTR
3514static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00003515#ifdef _CS_ARCHITECTURE
3516 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
3517#endif
3518#ifdef _CS_HOSTNAME
3519 {"CS_HOSTNAME", _CS_HOSTNAME},
3520#endif
3521#ifdef _CS_HW_PROVIDER
3522 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
3523#endif
3524#ifdef _CS_HW_SERIAL
3525 {"CS_HW_SERIAL", _CS_HW_SERIAL},
3526#endif
3527#ifdef _CS_INITTAB_NAME
3528 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
3529#endif
Fred Drakec9680921999-12-13 16:37:25 +00003530#ifdef _CS_LFS64_CFLAGS
3531 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
3532#endif
3533#ifdef _CS_LFS64_LDFLAGS
3534 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
3535#endif
3536#ifdef _CS_LFS64_LIBS
3537 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
3538#endif
3539#ifdef _CS_LFS64_LINTFLAGS
3540 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
3541#endif
3542#ifdef _CS_LFS_CFLAGS
3543 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
3544#endif
3545#ifdef _CS_LFS_LDFLAGS
3546 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
3547#endif
3548#ifdef _CS_LFS_LIBS
3549 {"CS_LFS_LIBS", _CS_LFS_LIBS},
3550#endif
3551#ifdef _CS_LFS_LINTFLAGS
3552 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
3553#endif
Fred Draked86ed291999-12-15 15:34:33 +00003554#ifdef _CS_MACHINE
3555 {"CS_MACHINE", _CS_MACHINE},
3556#endif
Fred Drakec9680921999-12-13 16:37:25 +00003557#ifdef _CS_PATH
3558 {"CS_PATH", _CS_PATH},
3559#endif
Fred Draked86ed291999-12-15 15:34:33 +00003560#ifdef _CS_RELEASE
3561 {"CS_RELEASE", _CS_RELEASE},
3562#endif
3563#ifdef _CS_SRPC_DOMAIN
3564 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
3565#endif
3566#ifdef _CS_SYSNAME
3567 {"CS_SYSNAME", _CS_SYSNAME},
3568#endif
3569#ifdef _CS_VERSION
3570 {"CS_VERSION", _CS_VERSION},
3571#endif
Fred Drakec9680921999-12-13 16:37:25 +00003572#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
3573 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
3574#endif
3575#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
3576 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
3577#endif
3578#ifdef _CS_XBS5_ILP32_OFF32_LIBS
3579 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
3580#endif
3581#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
3582 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
3583#endif
3584#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
3585 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
3586#endif
3587#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
3588 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
3589#endif
3590#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
3591 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
3592#endif
3593#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
3594 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
3595#endif
3596#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
3597 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
3598#endif
3599#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
3600 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
3601#endif
3602#ifdef _CS_XBS5_LP64_OFF64_LIBS
3603 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
3604#endif
3605#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
3606 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
3607#endif
3608#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
3609 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
3610#endif
3611#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
3612 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
3613#endif
3614#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
3615 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
3616#endif
3617#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
3618 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
3619#endif
Fred Draked86ed291999-12-15 15:34:33 +00003620#ifdef _MIPS_CS_AVAIL_PROCESSORS
3621 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
3622#endif
3623#ifdef _MIPS_CS_BASE
3624 {"MIPS_CS_BASE", _MIPS_CS_BASE},
3625#endif
3626#ifdef _MIPS_CS_HOSTID
3627 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
3628#endif
3629#ifdef _MIPS_CS_HW_NAME
3630 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
3631#endif
3632#ifdef _MIPS_CS_NUM_PROCESSORS
3633 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
3634#endif
3635#ifdef _MIPS_CS_OSREL_MAJ
3636 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
3637#endif
3638#ifdef _MIPS_CS_OSREL_MIN
3639 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
3640#endif
3641#ifdef _MIPS_CS_OSREL_PATCH
3642 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
3643#endif
3644#ifdef _MIPS_CS_OS_NAME
3645 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
3646#endif
3647#ifdef _MIPS_CS_OS_PROVIDER
3648 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
3649#endif
3650#ifdef _MIPS_CS_PROCESSORS
3651 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
3652#endif
3653#ifdef _MIPS_CS_SERIAL
3654 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
3655#endif
3656#ifdef _MIPS_CS_VENDOR
3657 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
3658#endif
Fred Drakec9680921999-12-13 16:37:25 +00003659};
3660
3661static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003662conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00003663{
3664 return conv_confname(arg, valuep, posix_constants_confstr,
3665 sizeof(posix_constants_confstr)
3666 / sizeof(struct constdef));
3667}
3668
3669static char posix_confstr__doc__[] = "\
3670confstr(name) -> string\n\
3671Return a string-valued system configuration variable.";
3672
3673static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003674posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00003675{
3676 PyObject *result = NULL;
3677 int name;
3678 char buffer[64];
3679
3680 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
3681 int len = confstr(name, buffer, sizeof(buffer));
3682
Fred Drakec9680921999-12-13 16:37:25 +00003683 errno = 0;
3684 if (len == 0) {
3685 if (errno != 0)
3686 posix_error();
3687 else
3688 result = PyString_FromString("");
3689 }
3690 else {
3691 if (len >= sizeof(buffer)) {
3692 result = PyString_FromStringAndSize(NULL, len);
3693 if (result != NULL)
3694 confstr(name, PyString_AS_STRING(result), len+1);
3695 }
3696 else
3697 result = PyString_FromString(buffer);
3698 }
3699 }
3700 return result;
3701}
3702#endif
3703
3704
3705#ifdef HAVE_SYSCONF
3706static struct constdef posix_constants_sysconf[] = {
3707#ifdef _SC_2_CHAR_TERM
3708 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
3709#endif
3710#ifdef _SC_2_C_BIND
3711 {"SC_2_C_BIND", _SC_2_C_BIND},
3712#endif
3713#ifdef _SC_2_C_DEV
3714 {"SC_2_C_DEV", _SC_2_C_DEV},
3715#endif
3716#ifdef _SC_2_C_VERSION
3717 {"SC_2_C_VERSION", _SC_2_C_VERSION},
3718#endif
3719#ifdef _SC_2_FORT_DEV
3720 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
3721#endif
3722#ifdef _SC_2_FORT_RUN
3723 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
3724#endif
3725#ifdef _SC_2_LOCALEDEF
3726 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
3727#endif
3728#ifdef _SC_2_SW_DEV
3729 {"SC_2_SW_DEV", _SC_2_SW_DEV},
3730#endif
3731#ifdef _SC_2_UPE
3732 {"SC_2_UPE", _SC_2_UPE},
3733#endif
3734#ifdef _SC_2_VERSION
3735 {"SC_2_VERSION", _SC_2_VERSION},
3736#endif
Fred Draked86ed291999-12-15 15:34:33 +00003737#ifdef _SC_ABI_ASYNCHRONOUS_IO
3738 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
3739#endif
3740#ifdef _SC_ACL
3741 {"SC_ACL", _SC_ACL},
3742#endif
Fred Drakec9680921999-12-13 16:37:25 +00003743#ifdef _SC_AIO_LISTIO_MAX
3744 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
3745#endif
Fred Drakec9680921999-12-13 16:37:25 +00003746#ifdef _SC_AIO_MAX
3747 {"SC_AIO_MAX", _SC_AIO_MAX},
3748#endif
3749#ifdef _SC_AIO_PRIO_DELTA_MAX
3750 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
3751#endif
3752#ifdef _SC_ARG_MAX
3753 {"SC_ARG_MAX", _SC_ARG_MAX},
3754#endif
3755#ifdef _SC_ASYNCHRONOUS_IO
3756 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
3757#endif
3758#ifdef _SC_ATEXIT_MAX
3759 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
3760#endif
Fred Draked86ed291999-12-15 15:34:33 +00003761#ifdef _SC_AUDIT
3762 {"SC_AUDIT", _SC_AUDIT},
3763#endif
Fred Drakec9680921999-12-13 16:37:25 +00003764#ifdef _SC_AVPHYS_PAGES
3765 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
3766#endif
3767#ifdef _SC_BC_BASE_MAX
3768 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
3769#endif
3770#ifdef _SC_BC_DIM_MAX
3771 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
3772#endif
3773#ifdef _SC_BC_SCALE_MAX
3774 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
3775#endif
3776#ifdef _SC_BC_STRING_MAX
3777 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
3778#endif
Fred Draked86ed291999-12-15 15:34:33 +00003779#ifdef _SC_CAP
3780 {"SC_CAP", _SC_CAP},
3781#endif
Fred Drakec9680921999-12-13 16:37:25 +00003782#ifdef _SC_CHARCLASS_NAME_MAX
3783 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
3784#endif
3785#ifdef _SC_CHAR_BIT
3786 {"SC_CHAR_BIT", _SC_CHAR_BIT},
3787#endif
3788#ifdef _SC_CHAR_MAX
3789 {"SC_CHAR_MAX", _SC_CHAR_MAX},
3790#endif
3791#ifdef _SC_CHAR_MIN
3792 {"SC_CHAR_MIN", _SC_CHAR_MIN},
3793#endif
3794#ifdef _SC_CHILD_MAX
3795 {"SC_CHILD_MAX", _SC_CHILD_MAX},
3796#endif
3797#ifdef _SC_CLK_TCK
3798 {"SC_CLK_TCK", _SC_CLK_TCK},
3799#endif
3800#ifdef _SC_COHER_BLKSZ
3801 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
3802#endif
3803#ifdef _SC_COLL_WEIGHTS_MAX
3804 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
3805#endif
3806#ifdef _SC_DCACHE_ASSOC
3807 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
3808#endif
3809#ifdef _SC_DCACHE_BLKSZ
3810 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
3811#endif
3812#ifdef _SC_DCACHE_LINESZ
3813 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
3814#endif
3815#ifdef _SC_DCACHE_SZ
3816 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
3817#endif
3818#ifdef _SC_DCACHE_TBLKSZ
3819 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
3820#endif
3821#ifdef _SC_DELAYTIMER_MAX
3822 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
3823#endif
3824#ifdef _SC_EQUIV_CLASS_MAX
3825 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
3826#endif
3827#ifdef _SC_EXPR_NEST_MAX
3828 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
3829#endif
3830#ifdef _SC_FSYNC
3831 {"SC_FSYNC", _SC_FSYNC},
3832#endif
3833#ifdef _SC_GETGR_R_SIZE_MAX
3834 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
3835#endif
3836#ifdef _SC_GETPW_R_SIZE_MAX
3837 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
3838#endif
3839#ifdef _SC_ICACHE_ASSOC
3840 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
3841#endif
3842#ifdef _SC_ICACHE_BLKSZ
3843 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
3844#endif
3845#ifdef _SC_ICACHE_LINESZ
3846 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
3847#endif
3848#ifdef _SC_ICACHE_SZ
3849 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
3850#endif
Fred Draked86ed291999-12-15 15:34:33 +00003851#ifdef _SC_INF
3852 {"SC_INF", _SC_INF},
3853#endif
Fred Drakec9680921999-12-13 16:37:25 +00003854#ifdef _SC_INT_MAX
3855 {"SC_INT_MAX", _SC_INT_MAX},
3856#endif
3857#ifdef _SC_INT_MIN
3858 {"SC_INT_MIN", _SC_INT_MIN},
3859#endif
3860#ifdef _SC_IOV_MAX
3861 {"SC_IOV_MAX", _SC_IOV_MAX},
3862#endif
Fred Draked86ed291999-12-15 15:34:33 +00003863#ifdef _SC_IP_SECOPTS
3864 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
3865#endif
Fred Drakec9680921999-12-13 16:37:25 +00003866#ifdef _SC_JOB_CONTROL
3867 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
3868#endif
Fred Draked86ed291999-12-15 15:34:33 +00003869#ifdef _SC_KERN_POINTERS
3870 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
3871#endif
3872#ifdef _SC_KERN_SIM
3873 {"SC_KERN_SIM", _SC_KERN_SIM},
3874#endif
Fred Drakec9680921999-12-13 16:37:25 +00003875#ifdef _SC_LINE_MAX
3876 {"SC_LINE_MAX", _SC_LINE_MAX},
3877#endif
3878#ifdef _SC_LOGIN_NAME_MAX
3879 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
3880#endif
3881#ifdef _SC_LOGNAME_MAX
3882 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
3883#endif
3884#ifdef _SC_LONG_BIT
3885 {"SC_LONG_BIT", _SC_LONG_BIT},
3886#endif
Fred Draked86ed291999-12-15 15:34:33 +00003887#ifdef _SC_MAC
3888 {"SC_MAC", _SC_MAC},
3889#endif
Fred Drakec9680921999-12-13 16:37:25 +00003890#ifdef _SC_MAPPED_FILES
3891 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
3892#endif
3893#ifdef _SC_MAXPID
3894 {"SC_MAXPID", _SC_MAXPID},
3895#endif
3896#ifdef _SC_MB_LEN_MAX
3897 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
3898#endif
3899#ifdef _SC_MEMLOCK
3900 {"SC_MEMLOCK", _SC_MEMLOCK},
3901#endif
3902#ifdef _SC_MEMLOCK_RANGE
3903 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
3904#endif
3905#ifdef _SC_MEMORY_PROTECTION
3906 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
3907#endif
3908#ifdef _SC_MESSAGE_PASSING
3909 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
3910#endif
Fred Draked86ed291999-12-15 15:34:33 +00003911#ifdef _SC_MMAP_FIXED_ALIGNMENT
3912 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
3913#endif
Fred Drakec9680921999-12-13 16:37:25 +00003914#ifdef _SC_MQ_OPEN_MAX
3915 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
3916#endif
3917#ifdef _SC_MQ_PRIO_MAX
3918 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
3919#endif
Fred Draked86ed291999-12-15 15:34:33 +00003920#ifdef _SC_NACLS_MAX
3921 {"SC_NACLS_MAX", _SC_NACLS_MAX},
3922#endif
Fred Drakec9680921999-12-13 16:37:25 +00003923#ifdef _SC_NGROUPS_MAX
3924 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
3925#endif
3926#ifdef _SC_NL_ARGMAX
3927 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
3928#endif
3929#ifdef _SC_NL_LANGMAX
3930 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
3931#endif
3932#ifdef _SC_NL_MSGMAX
3933 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
3934#endif
3935#ifdef _SC_NL_NMAX
3936 {"SC_NL_NMAX", _SC_NL_NMAX},
3937#endif
3938#ifdef _SC_NL_SETMAX
3939 {"SC_NL_SETMAX", _SC_NL_SETMAX},
3940#endif
3941#ifdef _SC_NL_TEXTMAX
3942 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
3943#endif
3944#ifdef _SC_NPROCESSORS_CONF
3945 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
3946#endif
3947#ifdef _SC_NPROCESSORS_ONLN
3948 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
3949#endif
Fred Draked86ed291999-12-15 15:34:33 +00003950#ifdef _SC_NPROC_CONF
3951 {"SC_NPROC_CONF", _SC_NPROC_CONF},
3952#endif
3953#ifdef _SC_NPROC_ONLN
3954 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
3955#endif
Fred Drakec9680921999-12-13 16:37:25 +00003956#ifdef _SC_NZERO
3957 {"SC_NZERO", _SC_NZERO},
3958#endif
3959#ifdef _SC_OPEN_MAX
3960 {"SC_OPEN_MAX", _SC_OPEN_MAX},
3961#endif
3962#ifdef _SC_PAGESIZE
3963 {"SC_PAGESIZE", _SC_PAGESIZE},
3964#endif
3965#ifdef _SC_PAGE_SIZE
3966 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
3967#endif
3968#ifdef _SC_PASS_MAX
3969 {"SC_PASS_MAX", _SC_PASS_MAX},
3970#endif
3971#ifdef _SC_PHYS_PAGES
3972 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
3973#endif
3974#ifdef _SC_PII
3975 {"SC_PII", _SC_PII},
3976#endif
3977#ifdef _SC_PII_INTERNET
3978 {"SC_PII_INTERNET", _SC_PII_INTERNET},
3979#endif
3980#ifdef _SC_PII_INTERNET_DGRAM
3981 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
3982#endif
3983#ifdef _SC_PII_INTERNET_STREAM
3984 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
3985#endif
3986#ifdef _SC_PII_OSI
3987 {"SC_PII_OSI", _SC_PII_OSI},
3988#endif
3989#ifdef _SC_PII_OSI_CLTS
3990 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
3991#endif
3992#ifdef _SC_PII_OSI_COTS
3993 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
3994#endif
3995#ifdef _SC_PII_OSI_M
3996 {"SC_PII_OSI_M", _SC_PII_OSI_M},
3997#endif
3998#ifdef _SC_PII_SOCKET
3999 {"SC_PII_SOCKET", _SC_PII_SOCKET},
4000#endif
4001#ifdef _SC_PII_XTI
4002 {"SC_PII_XTI", _SC_PII_XTI},
4003#endif
4004#ifdef _SC_POLL
4005 {"SC_POLL", _SC_POLL},
4006#endif
4007#ifdef _SC_PRIORITIZED_IO
4008 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
4009#endif
4010#ifdef _SC_PRIORITY_SCHEDULING
4011 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
4012#endif
4013#ifdef _SC_REALTIME_SIGNALS
4014 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
4015#endif
4016#ifdef _SC_RE_DUP_MAX
4017 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
4018#endif
4019#ifdef _SC_RTSIG_MAX
4020 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
4021#endif
4022#ifdef _SC_SAVED_IDS
4023 {"SC_SAVED_IDS", _SC_SAVED_IDS},
4024#endif
4025#ifdef _SC_SCHAR_MAX
4026 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
4027#endif
4028#ifdef _SC_SCHAR_MIN
4029 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
4030#endif
4031#ifdef _SC_SELECT
4032 {"SC_SELECT", _SC_SELECT},
4033#endif
4034#ifdef _SC_SEMAPHORES
4035 {"SC_SEMAPHORES", _SC_SEMAPHORES},
4036#endif
4037#ifdef _SC_SEM_NSEMS_MAX
4038 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
4039#endif
4040#ifdef _SC_SEM_VALUE_MAX
4041 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
4042#endif
4043#ifdef _SC_SHARED_MEMORY_OBJECTS
4044 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
4045#endif
4046#ifdef _SC_SHRT_MAX
4047 {"SC_SHRT_MAX", _SC_SHRT_MAX},
4048#endif
4049#ifdef _SC_SHRT_MIN
4050 {"SC_SHRT_MIN", _SC_SHRT_MIN},
4051#endif
4052#ifdef _SC_SIGQUEUE_MAX
4053 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
4054#endif
4055#ifdef _SC_SIGRT_MAX
4056 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
4057#endif
4058#ifdef _SC_SIGRT_MIN
4059 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
4060#endif
Fred Draked86ed291999-12-15 15:34:33 +00004061#ifdef _SC_SOFTPOWER
4062 {"SC_SOFTPOWER", _SC_SOFTPOWER},
4063#endif
Fred Drakec9680921999-12-13 16:37:25 +00004064#ifdef _SC_SPLIT_CACHE
4065 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
4066#endif
4067#ifdef _SC_SSIZE_MAX
4068 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
4069#endif
4070#ifdef _SC_STACK_PROT
4071 {"SC_STACK_PROT", _SC_STACK_PROT},
4072#endif
4073#ifdef _SC_STREAM_MAX
4074 {"SC_STREAM_MAX", _SC_STREAM_MAX},
4075#endif
4076#ifdef _SC_SYNCHRONIZED_IO
4077 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
4078#endif
4079#ifdef _SC_THREADS
4080 {"SC_THREADS", _SC_THREADS},
4081#endif
4082#ifdef _SC_THREAD_ATTR_STACKADDR
4083 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
4084#endif
4085#ifdef _SC_THREAD_ATTR_STACKSIZE
4086 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
4087#endif
4088#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
4089 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
4090#endif
4091#ifdef _SC_THREAD_KEYS_MAX
4092 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
4093#endif
4094#ifdef _SC_THREAD_PRIORITY_SCHEDULING
4095 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
4096#endif
4097#ifdef _SC_THREAD_PRIO_INHERIT
4098 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
4099#endif
4100#ifdef _SC_THREAD_PRIO_PROTECT
4101 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
4102#endif
4103#ifdef _SC_THREAD_PROCESS_SHARED
4104 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
4105#endif
4106#ifdef _SC_THREAD_SAFE_FUNCTIONS
4107 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
4108#endif
4109#ifdef _SC_THREAD_STACK_MIN
4110 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
4111#endif
4112#ifdef _SC_THREAD_THREADS_MAX
4113 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
4114#endif
4115#ifdef _SC_TIMERS
4116 {"SC_TIMERS", _SC_TIMERS},
4117#endif
4118#ifdef _SC_TIMER_MAX
4119 {"SC_TIMER_MAX", _SC_TIMER_MAX},
4120#endif
4121#ifdef _SC_TTY_NAME_MAX
4122 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
4123#endif
4124#ifdef _SC_TZNAME_MAX
4125 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
4126#endif
4127#ifdef _SC_T_IOV_MAX
4128 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
4129#endif
4130#ifdef _SC_UCHAR_MAX
4131 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
4132#endif
4133#ifdef _SC_UINT_MAX
4134 {"SC_UINT_MAX", _SC_UINT_MAX},
4135#endif
4136#ifdef _SC_UIO_MAXIOV
4137 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
4138#endif
4139#ifdef _SC_ULONG_MAX
4140 {"SC_ULONG_MAX", _SC_ULONG_MAX},
4141#endif
4142#ifdef _SC_USHRT_MAX
4143 {"SC_USHRT_MAX", _SC_USHRT_MAX},
4144#endif
4145#ifdef _SC_VERSION
4146 {"SC_VERSION", _SC_VERSION},
4147#endif
4148#ifdef _SC_WORD_BIT
4149 {"SC_WORD_BIT", _SC_WORD_BIT},
4150#endif
4151#ifdef _SC_XBS5_ILP32_OFF32
4152 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
4153#endif
4154#ifdef _SC_XBS5_ILP32_OFFBIG
4155 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
4156#endif
4157#ifdef _SC_XBS5_LP64_OFF64
4158 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
4159#endif
4160#ifdef _SC_XBS5_LPBIG_OFFBIG
4161 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
4162#endif
4163#ifdef _SC_XOPEN_CRYPT
4164 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
4165#endif
4166#ifdef _SC_XOPEN_ENH_I18N
4167 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
4168#endif
4169#ifdef _SC_XOPEN_LEGACY
4170 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
4171#endif
4172#ifdef _SC_XOPEN_REALTIME
4173 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
4174#endif
4175#ifdef _SC_XOPEN_REALTIME_THREADS
4176 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
4177#endif
4178#ifdef _SC_XOPEN_SHM
4179 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
4180#endif
4181#ifdef _SC_XOPEN_UNIX
4182 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
4183#endif
4184#ifdef _SC_XOPEN_VERSION
4185 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
4186#endif
4187#ifdef _SC_XOPEN_XCU_VERSION
4188 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
4189#endif
4190#ifdef _SC_XOPEN_XPG2
4191 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
4192#endif
4193#ifdef _SC_XOPEN_XPG3
4194 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
4195#endif
4196#ifdef _SC_XOPEN_XPG4
4197 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
4198#endif
4199};
4200
4201static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004202conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004203{
4204 return conv_confname(arg, valuep, posix_constants_sysconf,
4205 sizeof(posix_constants_sysconf)
4206 / sizeof(struct constdef));
4207}
4208
4209static char posix_sysconf__doc__[] = "\
4210sysconf(name) -> integer\n\
4211Return an integer-valued system configuration variable.";
4212
4213static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004214posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004215{
4216 PyObject *result = NULL;
4217 int name;
4218
4219 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
4220 int value;
4221
4222 errno = 0;
4223 value = sysconf(name);
4224 if (value == -1 && errno != 0)
4225 posix_error();
4226 else
4227 result = PyInt_FromLong(value);
4228 }
4229 return result;
4230}
4231#endif
4232
4233
Fred Drakebec628d1999-12-15 18:31:10 +00004234/* This code is used to ensure that the tables of configuration value names
4235 * are in sorted order as required by conv_confname(), and also to build the
4236 * the exported dictionaries that are used to publish information about the
4237 * names available on the host platform.
4238 *
4239 * Sorting the table at runtime ensures that the table is properly ordered
4240 * when used, even for platforms we're not able to test on. It also makes
4241 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00004242 */
Fred Drakebec628d1999-12-15 18:31:10 +00004243
4244static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004245cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00004246{
4247 const struct constdef *c1 =
4248 (const struct constdef *) v1;
4249 const struct constdef *c2 =
4250 (const struct constdef *) v2;
4251
4252 return strcmp(c1->name, c2->name);
4253}
4254
4255static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004256setup_confname_table(struct constdef *table, size_t tablesize,
4257 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00004258{
Fred Drakebec628d1999-12-15 18:31:10 +00004259 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00004260 size_t i;
4261 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00004262
4263 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
4264 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00004265 if (d == NULL)
4266 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004267
Barry Warsaw3155db32000-04-13 15:20:40 +00004268 for (i=0; i < tablesize; ++i) {
4269 PyObject *o = PyInt_FromLong(table[i].value);
4270 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
4271 Py_XDECREF(o);
4272 Py_DECREF(d);
4273 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004274 }
Barry Warsaw3155db32000-04-13 15:20:40 +00004275 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00004276 }
Barry Warsaw3155db32000-04-13 15:20:40 +00004277 status = PyDict_SetItemString(moddict, tablename, d);
4278 Py_DECREF(d);
4279 return status;
Fred Draked86ed291999-12-15 15:34:33 +00004280}
4281
Fred Drakebec628d1999-12-15 18:31:10 +00004282/* Return -1 on failure, 0 on success. */
4283static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004284setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00004285{
4286#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00004287 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00004288 sizeof(posix_constants_pathconf)
4289 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00004290 "pathconf_names", moddict))
4291 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004292#endif
4293#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00004294 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00004295 sizeof(posix_constants_confstr)
4296 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00004297 "confstr_names", moddict))
4298 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004299#endif
4300#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00004301 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00004302 sizeof(posix_constants_sysconf)
4303 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00004304 "sysconf_names", moddict))
4305 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004306#endif
Fred Drakebec628d1999-12-15 18:31:10 +00004307 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00004308}
Fred Draked86ed291999-12-15 15:34:33 +00004309
4310
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004311static char posix_abort__doc__[] = "\
4312abort() -> does not return!\n\
4313Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
4314in the hardest way possible on the hosting operating system.";
4315
4316static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004317posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004318{
4319 if (!PyArg_ParseTuple(args, ":abort"))
4320 return NULL;
4321 abort();
4322 /*NOTREACHED*/
4323 Py_FatalError("abort() called from Python code didn't abort!");
4324 return NULL;
4325}
Fred Drakebec628d1999-12-15 18:31:10 +00004326
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004327
4328static PyMethodDef posix_methods[] = {
4329 {"access", posix_access, METH_VARARGS, posix_access__doc__},
4330#ifdef HAVE_TTYNAME
4331 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
4332#endif
4333 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
4334 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004335#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004336 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004337#endif /* HAVE_CHOWN */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004338#ifdef HAVE_CTERMID
4339 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
4340#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00004341#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004342 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00004343#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004344#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004345 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004346#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004347 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
4348 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
4349 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004350#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004351 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004352#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004353#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004354 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004355#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004356 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
4357 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
4358 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004359#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004360 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004361#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004362#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004363 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004364#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004365 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004366#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004367 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004368#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004369 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
4370 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
4371 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004372#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004373 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004374#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004375 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004376#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004377 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
4378 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004379#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00004380#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004381 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
4382 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00004383#endif /* HAVE_SPAWNV */
Guido van Rossumad0ee831995-03-01 10:34:45 +00004384#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004385 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004386#endif /* HAVE_FORK */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004387#ifdef HAVE_OPENPTY
4388 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
4389#endif /* HAVE_OPENPTY */
4390#ifdef HAVE_FORKPTY
4391 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
4392#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00004393#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004394 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004395#endif /* HAVE_GETEGID */
4396#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004397 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004398#endif /* HAVE_GETEUID */
4399#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004400 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004401#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00004402#ifdef HAVE_GETGROUPS
4403 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
4404#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004405 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004406#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004407 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004408#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00004409#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004410 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004411#endif /* HAVE_GETPPID */
4412#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004413 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004414#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00004415#ifdef HAVE_GETLOGIN
4416 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
4417#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00004418#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004419 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004420#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00004421#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004422 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00004423#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004424#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004425 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004426#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004427#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004428 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004429#endif /* HAVE_SETUID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004430#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004431 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004432#endif /* HAVE_SETGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004433#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004434 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004435#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00004436#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004437 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004438#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004439#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004440 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004441#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004442#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004443 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004444#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004445#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004446 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004447#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004448#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004449 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004450#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004451#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004452 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004453#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004454 {"open", posix_open, METH_VARARGS, posix_open__doc__},
4455 {"close", posix_close, METH_VARARGS, posix_close__doc__},
4456 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
4457 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
4458 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
4459 {"read", posix_read, METH_VARARGS, posix_read__doc__},
4460 {"write", posix_write, METH_VARARGS, posix_write__doc__},
4461 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
4462 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004463#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004464 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004465#endif
4466#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004467 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004468#endif
4469#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004470 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004471#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004472#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004473 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004474#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00004475#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004476 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00004477#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00004478#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004479 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00004480#endif
4481#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004482 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00004483#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00004484#ifdef HAVE_SYS_WAIT_H
4485#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004486 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00004487#endif /* WIFSTOPPED */
4488#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004489 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00004490#endif /* WIFSIGNALED */
4491#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004492 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00004493#endif /* WIFEXITED */
4494#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004495 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00004496#endif /* WEXITSTATUS */
4497#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004498 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00004499#endif /* WTERMSIG */
4500#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004501 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00004502#endif /* WSTOPSIG */
4503#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004504#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004505 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00004506#endif
4507#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004508 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00004509#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004510#ifdef HAVE_TMPNAM
4511 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
4512#endif
4513#ifdef HAVE_TEMPNAM
4514 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
4515#endif
4516#ifdef HAVE_TMPNAM
4517 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
4518#endif
Fred Drakec9680921999-12-13 16:37:25 +00004519#ifdef HAVE_CONFSTR
4520 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
4521#endif
4522#ifdef HAVE_SYSCONF
4523 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
4524#endif
4525#ifdef HAVE_FPATHCONF
4526 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
4527#endif
4528#ifdef HAVE_PATHCONF
4529 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
4530#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004531 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004532 {NULL, NULL} /* Sentinel */
4533};
4534
4535
Barry Warsaw4a342091996-12-19 23:50:02 +00004536static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004537ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00004538{
4539 PyObject* v = PyInt_FromLong(value);
4540 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
4541 return -1; /* triggers fatal error */
4542
4543 Py_DECREF(v);
4544 return 0;
4545}
4546
Guido van Rossumd48f2521997-12-05 22:19:34 +00004547#if defined(PYOS_OS2)
4548/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
4549static int insertvalues(PyObject *d)
4550{
4551 APIRET rc;
4552 ULONG values[QSV_MAX+1];
4553 PyObject *v;
4554 char *ver, tmp[10];
4555
4556 Py_BEGIN_ALLOW_THREADS
4557 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
4558 Py_END_ALLOW_THREADS
4559
4560 if (rc != NO_ERROR) {
4561 os2_error(rc);
4562 return -1;
4563 }
4564
4565 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
4566 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
4567 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
4568 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
4569 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
4570 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
4571 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
4572
4573 switch (values[QSV_VERSION_MINOR]) {
4574 case 0: ver = "2.00"; break;
4575 case 10: ver = "2.10"; break;
4576 case 11: ver = "2.11"; break;
4577 case 30: ver = "3.00"; break;
4578 case 40: ver = "4.00"; break;
4579 case 50: ver = "5.00"; break;
4580 default:
4581 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
4582 values[QSV_VERSION_MINOR]);
4583 ver = &tmp[0];
4584 }
4585
4586 /* Add Indicator of the Version of the Operating System */
4587 v = PyString_FromString(ver);
4588 if (!v || PyDict_SetItemString(d, "version", v) < 0)
4589 return -1;
4590 Py_DECREF(v);
4591
4592 /* Add Indicator of Which Drive was Used to Boot the System */
4593 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
4594 tmp[1] = ':';
4595 tmp[2] = '\0';
4596
4597 v = PyString_FromString(tmp);
4598 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
4599 return -1;
4600 Py_DECREF(v);
4601
4602 return 0;
4603}
4604#endif
4605
Barry Warsaw4a342091996-12-19 23:50:02 +00004606static int
4607all_ins(d)
4608 PyObject* d;
4609{
Guido van Rossum94f6f721999-01-06 18:42:14 +00004610#ifdef F_OK
4611 if (ins(d, "F_OK", (long)F_OK)) return -1;
4612#endif
4613#ifdef R_OK
4614 if (ins(d, "R_OK", (long)R_OK)) return -1;
4615#endif
4616#ifdef W_OK
4617 if (ins(d, "W_OK", (long)W_OK)) return -1;
4618#endif
4619#ifdef X_OK
4620 if (ins(d, "X_OK", (long)X_OK)) return -1;
4621#endif
Fred Drakec9680921999-12-13 16:37:25 +00004622#ifdef NGROUPS_MAX
4623 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
4624#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004625#ifdef TMP_MAX
4626 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
4627#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00004628#ifdef WNOHANG
4629 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
4630#endif
4631#ifdef O_RDONLY
4632 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
4633#endif
4634#ifdef O_WRONLY
4635 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
4636#endif
4637#ifdef O_RDWR
4638 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
4639#endif
4640#ifdef O_NDELAY
4641 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
4642#endif
4643#ifdef O_NONBLOCK
4644 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
4645#endif
4646#ifdef O_APPEND
4647 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
4648#endif
4649#ifdef O_DSYNC
4650 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
4651#endif
4652#ifdef O_RSYNC
4653 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
4654#endif
4655#ifdef O_SYNC
4656 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
4657#endif
4658#ifdef O_NOCTTY
4659 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
4660#endif
4661#ifdef O_CREAT
4662 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
4663#endif
4664#ifdef O_EXCL
4665 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
4666#endif
4667#ifdef O_TRUNC
4668 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
4669#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00004670#ifdef O_BINARY
4671 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
4672#endif
4673#ifdef O_TEXT
4674 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
4675#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00004676
Guido van Rossum246bc171999-02-01 23:54:31 +00004677#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00004678 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
4679 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
4680 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
4681 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
4682 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00004683#endif
4684
Guido van Rossumd48f2521997-12-05 22:19:34 +00004685#if defined(PYOS_OS2)
4686 if (insertvalues(d)) return -1;
4687#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00004688 return 0;
4689}
4690
4691
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004692#if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00004693#define INITFUNC initnt
4694#define MODNAME "nt"
4695#else
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004696#if defined(PYOS_OS2)
4697#define INITFUNC initos2
4698#define MODNAME "os2"
4699#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00004700#define INITFUNC initposix
4701#define MODNAME "posix"
4702#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004703#endif
Guido van Rossum0cb96de1997-10-01 04:29:29 +00004704
Guido van Rossum3886bb61998-12-04 18:50:17 +00004705DL_EXPORT(void)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00004706INITFUNC()
Guido van Rossumb6775db1994-08-01 11:34:53 +00004707{
Barry Warsaw53699e91996-12-10 23:23:01 +00004708 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00004709
Guido van Rossum0cb96de1997-10-01 04:29:29 +00004710 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004711 posix_methods,
4712 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00004713 (PyObject *)NULL,
4714 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00004715 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004716
Guido van Rossum0cb96de1997-10-01 04:29:29 +00004717 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004718 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00004719 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00004720 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00004721 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00004722
Barry Warsaw4a342091996-12-19 23:50:02 +00004723 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00004724 return;
4725
Fred Drakebec628d1999-12-15 18:31:10 +00004726 if (setup_confname_tables(d))
4727 return;
4728
Barry Warsawca74da41999-02-09 19:31:45 +00004729 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00004730
Guido van Rossumb3d39562000-01-31 18:41:26 +00004731#ifdef HAVE_PUTENV
Fred Drake762e2061999-08-26 17:23:54 +00004732 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00004733#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004734}